-
用
file Image.bin
查看文件类型,发现是DOS/MBR boot sector -
下面简单记录一下DOS分区体系的主引导记录扇区-MBR
-
使用 DOS 分区体系时,磁盘的第一个扇区――也就是 0 号扇区被称为主引导记录扇区,也称为 MBR( 主引导记录, Master Boot Recorder -- MBR) 。当计算机启动并完成自检后,首先会寻找磁盘的 MBR 扇区并读取其中的引导记录,然后将系统控制权交给它。
-
MBR 由 446 个字节的引导代码、 64 个字节的主分区表及 2 个字节的签名值“ 55AA ”组成。
-
***引导代码:***MBR 接管系统的控制权后,引导代码负责对其他代码信息进行检查(比如查看是否有“ 55AA ”有效标记)并进一步引导系统。
-
分区表:分区表负责描述磁盘内的分区情况。
-
“ 55AA ”有效标志。“ 55AA ”标志做为有效标志以通知系统该 MBR 扇区是否有效,如果该标志丢失或损坏,磁盘将会显示为“未初始化”。
-
放入010中找到此签名,那么前面的就是主引导扇区的代码
-
IDA将0-0x200的数据转换成汇编代码
-
seg000:0000 EA 05 00 C0 07 jmp far ptr 7C0h:5 seg000:0000 seg000:0005 ; --------------------------------------------------------------------------- seg000:0005 8C C8 mov ax, cs seg000:0007 8E D8 mov ds, ax seg000:0009 8E D0 mov ss, ax seg000:000B BC 00 04 mov sp, 400h seg000:000E FC cld seg000:000F B8 03 00 mov ax, 3 seg000:0012 CD 10 int 10h ; - VIDEO - SET VIDEO MODE seg000:0012 ; AL = mode seg000:0012 seg000:0014 BA 00 00 mov dx, 0 seg000:0017 B9 02 00 mov cx, 2 seg000:001A B8 00 10 mov ax, 1000h seg000:001D 8E C0 mov es, ax seg000:001F assume es:nothing seg000:001F 31 DB xor bx, bx seg000:0021 B8 28 02 mov ax, 228h seg000:0024 CD 13 int 13h ; DISK - READ SECTORS INTO MEMORY seg000:0024 ; AL = number of sectors to read, CH = track, CL = sector seg000:0024 ; DH = head, DL = drive, ES:BX -> buffer to fill seg000:0024 ; Return: CF set on error, AH = status, AL = number of sectors read seg000:0024 seg000:0026 73 02 jnb short loc_2A seg000:0026 seg000:0028 seg000:0028 loc_28: ; CODE XREF: seg000:loc_28↓j seg000:0028 EB FE jmp short loc_28 seg000:0028 seg000:002A ; --------------------------------------------------------------------------- seg000:002A seg000:002A loc_2A: ; CODE XREF: seg000:0026↑j seg000:002A FA cli seg000:002B B8 00 10 mov ax, 1000h seg000:002E 8E D8 mov ds, ax seg000:0030 assume ds:nothing seg000:0030 31 C0 xor ax, ax seg000:0032 8E C0 mov es, ax seg000:0034 assume es:nothing seg000:0034 B9 00 20 mov cx, 2000h seg000:0037 29 F6 sub si, si seg000:0039 29 FF sub di, di seg000:003B F3 A4 rep movsb seg000:003D B8 C0 07 mov ax, 7C0h seg000:003D seg000:0040 seg000:0040 loc_40: ; DATA XREF: seg000:0012↑r seg000:0040 8E D8 mov ds, ax seg000:0042 assume ds:nothing seg000:0042 0F 01 1E 6F 00 lidt fword ptr ds:6Fh seg000:0047 0F 01 16 75 00 lgdt fword ptr ds:75h seg000:0047 seg000:004C seg000:004C loc_4C: ; DATA XREF: seg000:0024↑r seg000:004C B8 01 00 mov ax, 1 seg000:004F 0F 01 F0 lmsw ax seg000:0052 EA 00 00 08 00 jmp far ptr byte_80 seg000:0052 seg000:0052 ; --------------------------------------------------------------------------- seg000:0057 00 00 00 00 00 00 00 00 FF 07+db 8 dup(0), 0FFh, 7, 3 dup(0), 9Ah, 0C0h, 0, 0FFh, 7, 3 dup(0), 92h, 0C0h, 7 dup(0), 0FFh, 7, 57h, 7Ch seg000:0057 00 00 00 9A C0 00 FF 07 00 00+db 7 dup(0) seg000:0080 00 00 00 00 00 00 00 00 00 00+byte_80 db 17Eh dup(0), 55h, 0AAh ; CODE XREF: seg000:0052↑J seg000:0080 00 00 00 00 00 00 00 00 00 00+seg000 ends seg000:0080 00 00 00 00 00 00 00 00 00 00+
-
下面分析上述汇编:
-
首先主引导扇区的地址被加载到0x7c00,跳转到0x7c05
-
然后初始化段寄存器和栈指针,然后用int 10h 是bios中断设置显示模式,字符和字符串输出等
-
int 13h就是直接磁盘服务,下面是一些用法:
-
1、功能 00H 功能描述:磁盘系统复位 入口参数:AH=00H DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘 出口参数:CF=0——操作成功,AH=00H,否则,AH=状态代码,参见功能号01H中的说明 2、功能 01H 功能描述:读取磁盘系统状态 入口参数:AH=01H DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘 出口参数:AH=00H,AL=状态代码,其定义如下: 00H — 无错 01H — 非法命令 02H — 地址目标未发现 03H — 磁盘写保护(软盘) 04H — 扇区未发现 05H — 复位失败(硬盘) 06H — 软盘取出(软盘) 07H — 错误的参数表(硬盘) 08H — DMA越界(软盘) 09H — DMA超过64K界限 0AH — 错误的扇区标志(硬盘) 0BH — 错误的磁道标志(硬盘) 0CH — 介质类型未发现(软盘) 0DH — 格式化时非法扇区号(硬盘) 0EH — 控制数据地址目标被发现(硬盘) 0FH — DMA仲裁越界(硬盘) 10H — 不正确的CRC或ECC编码 11H — ECC校正数据错(硬盘) CRC:Cyclic Redundancy Check code ECC:Error Checking & Correcting code 20H — 控制器失败 40H — 查找失败 80H — 磁盘超时(未响应) AAH — 驱动器未准备好(硬盘) BBH — 未定义的错误(硬盘) CCH — 写错误(硬盘) E0H — 状态寄存器错(硬盘) FFH — 检测操作失败(硬盘) 3、功能 02H 功能描述:读扇区 入口参数:AH=02H AL=扇区数 CH=柱面 CL=扇区 DH=磁头 DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘 ES:BX=缓冲区的地址 出口参数:CF=0——操作成功,AH=00H,AL=传输的扇区数,否则,AH=状态代码,参见功能号01H中的说明 4、功能 03H 功能描述:写扇区 入口参数:AH=03H AL=扇区数 CH=柱面 CL=扇区 DH=磁头 DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘 ES:BX=缓冲区的地址 出口参数:CF=0——操作成功,AH=00H,AL=传输的扇区数,否则,AH=状态代码,参见功能号01H中的说明 5、功能 04H 功能描述:检验扇区 入口参数:AH=04H AL=扇区数 CH=柱面 CL=扇区 DH=磁头 DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘 ES:BX=缓冲区的地址 出口参数:CF=0——操作成功,AH=00H,AL=被检验的扇区数,否则,AH=状态代码,参见功能号01H中的说明。 6、功能 05H 功能描述:格式化磁道 入口参数:AH=05H AL=交替(Interleave) CH=柱面 DH=磁头 DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘 ES:BX=地址域列表的地址 出口参数:CF=0——操作成功,AH=00H,否则,AH=状态代码,参见功能号01H中的说明。 7、功能 06H 功能描述:格式化坏磁道 入口参数:AH=06H AL=交替 CH=柱面 DH=磁头 DL=80H~0FFH:硬盘 ES:BX=地址域列表的地址 出口参数:CF=0——操作成功,AH=00H,否则,AH=状态代码,参见功能号01H中的说明 8、功能 07H 功能描述:格式化驱动器 入口参数:AH=07H AL=交替 CH=柱面 DL=80H~0FFH:硬盘 出口参数:CF=0——操作成功,AH=00H,否则,AH=状态代码,参见功能号01H中的说明 9、功能 08H 功能描述:读取驱动器参数 入口参数:AH=08H DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘 出口参数:CF=1——操作失败,AH=状态代码,参见功能号01H中的说明,否则, BL= 01H — 360K =02H — 1.2M =03H — 720K =04H — 1.44M CH=柱面数的低8位 CL的位7-6=柱面数的该2位 CL的位5-0=扇区数 DH=磁头数 DL=驱动器数 ES:DI=磁盘驱动器参数表地址 10、功能 09H 功能描述:初始化硬盘参数 入口参数:AH=09H DL=80H~0FFH:硬盘(还有有关参数表问题,在此从略) 出口参数:CF=0——操作成功,AH=00H,否则,AH=状态代码,参见功能号01H中的说明 11、功能 0AH 功能描述:读长扇区,每个扇区随带四个字节的ECC编码 入口参数:AH=0AH AL=扇区数 CH=柱面 CL=扇区 DH=磁头 DL=80H~0FFH:硬盘 ES:BX=缓冲区的地址 出口参数:CF=0——操作成功,AH=00H,AL=传输的扇区数,否则,AH=状态代码,参见功能号01H中的说明 12、功能 0BH 功能描述:写长扇区,每个扇区随带四个字节的ECC编码 入口参数:AH=0BH AL=扇区数 CH=柱面 CL=扇区 DH=磁头 DL=80H~0FFH:硬盘 ES:BX=缓冲区的地址 出口参数:CF=0——操作成功,AH=00H,AL=传输的扇区数,否则,AH=状态代码,参见功能号01H中的说明 13、功能 0CH 功能描述:查寻 入口参数:AH=0CH CH=柱面的低8位 CL(7-6位)=柱面的高2位 DH=磁头 DL=80H~0FFH:硬盘 出口参数:CF=0——操作成功,AH=00H,否则,AH=状态代码,参见功能号01H中的说明 14、功能 0DH 功能描述:硬盘系统复位 入口参数:AH=0DH DL=80H~0FFH:硬盘 出口参数:CF=0——操作成功,AH=00H,否则,AH=状态代码,参见功能号01H中的说明 15、功能 0EH 功能描述:读扇区缓冲区 入口参数:AH=0EH ES:BX=缓冲区的地址 出口参数:CF=0——操作成功,否则,AH=状态代码,参见功能号01H中的说明 16、功能 0FH 功能描述:写扇区缓冲区 入口参数:AH=0FH ES:BX=缓冲区的地址 出口参数:CF=0——操作成功,否则,AH=状态代码,参见功能号01H中的说明 17、功能 10H 功能描述:读取驱动器状态 入口参数:AH=10H DL=80H~0FFH:硬盘 出口参数:CF=0——操作成功,AH=00H,否则,AH=状态代码,参见功能号01H中的说明 18、功能 11H 功能描述:校准驱动器 入口参数:AH=11H DL=80H~0FFH:硬盘 出口参数:CF=0——操作成功,AH=00H,否则,AH=状态代码,参见功能号01H中的说明 19、功能 12H 功能描述:控制器RAM诊断 入口参数:AH=12H 出口参数:CF=0——操作成功,否则,AH=状态代码,参见功能号01H中的说明 20、功能 13H 功能描述:控制器驱动诊断 入口参数:AH=13H 出口参数:CF=0——操作成功,否则,AH=状态代码,参见功能号01H中的说明 21、功能 14H 功能描述:控制器内部诊断 入口参数:AH=14H 出口参数:CF=0——操作成功,否则,AH=状态代码,参见功能号01H中的说明 22、功能 15H 功能描述:读取磁盘类型 入口参数:AH=15H DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘 出口参数:CF=1——操作失败,AH=状态代码,参见功能号01H中的说明, 否则,AH=00H — 未安装驱动器 =01H — 无改变线支持的软盘驱动器 =02H — 带有改变线支持的软盘驱动器 =03H — 硬盘,CX:DX=512字节的扇区数 23、功能 16H 功能描述:读取磁盘变化状态 入口参数:AH=16H DL=00H~7FH:软盘 出口参数:CF=0——磁盘未改变,AH=00H,否则,AH=06H,参见功能号01H中的说明 24、功能 17H 功能描述:设置磁盘类型 入口参数:AH=17H DL=00H~7FH:软盘 AL=00H — 未用 =01H — 360K在360K驱动器中 =02H — 360K在1.2M驱动器中 =03H — 1.2M在1.2M驱动器中 =04H — 720K在720K驱动器中 出口参数:CF=0——操作成功,AH=00H,否则,AH=状态编码,参见功能号01H中的说明 25、功能 18H 功能描述:设置格式化媒体类型 入口参数:AH=18H CH=柱面数 CL=每磁道的扇区数 DL=00H~7FH:软盘 出口参数:CF=0——操作成功,AH=00H,ES:DI=介质类型参数表地址,否则,AH=状态编码,参见功能号01H中的说明 26、功能 19H 功能描述:磁头保护,仅在PS/2中有效,在此从略 27、功能 1AH 功能描述:格式化ESDI驱动器,仅在PS/2中有效,在此从略
-
找到汇编代码中AH的值为02h,对应用法:软盘(DL=0H) 上的0磁道(DH=0H)0柱面(CH=0H)2扇区(CL=2H)开始的28个扇区(AL=28H)读取(AH=02H)到内存的1000:0000h处(ES:BX=1000:0),然后跳到loc_2A处,这部分代码再将刚才读入的扇区数据移动到内存的0x00000000处
-
初始化IDT和GDT(lidt,lgdt)之后开启保护模式(Imsw)并且跳转至32位代码段 从0x200开始
继续转换成汇编代码,关于IDT与GDT:操作系统之GDT和IDT(三)_gdt idt-CSDN博客 -
这里切到保护,跳到32位
-
接着分析汇编:
-
seg000:00000200 sub_200 proc near seg000:00000200 B8 10 00 00 00 mov eax, 10h seg000:00000205 8E D8 mov ds, eax seg000:00000207 assume ds:nothing seg000:00000207 0F B2 25 5C 0B 00 00 lss esp, fword ptr ds:byte_C5C seg000:0000020E E8 78 00 00 00 call sub_28B seg000:0000020E seg000:00000213 seg000:00000213 loc_213: ; DATA XREF: sub_2BA+A↓r seg000:00000213 ; sub_2BA:loc_2E0↓w seg000:00000213 E8 6B 00 00 00 call sub_283 seg000:00000213 seg000:00000218 seg000:00000218 loc_218: ; DATA XREF: sub_28B+27↓r seg000:00000218 B8 10 00 00 00 mov eax, 10h seg000:0000021D 8E D8 mov ds, eax seg000:0000021F 8E C0 mov es, eax seg000:00000221 assume es:nothing seg000:00000221 seg000:00000221 loc_221: ; DATA XREF: sub_283↓r seg000:00000221 8E E0 mov fs, eax seg000:00000223 assume fs:nothing seg000:00000223 8E E8 mov gs, eax seg000:00000225 assume gs:nothing seg000:00000225 seg000:00000225 loc_225: ; DATA XREF: sub_28B+11↓o seg000:00000225 0F B2 25 5C 0B 00 00 lss esp, fword ptr ds:byte_C5C seg000:0000022C 31 DB xor ebx, ebx seg000:0000022C seg000:0000022E seg000:0000022E loc_22E: ; CODE XREF: sub_200+5D↓j seg000:0000022E 90 nop seg000:0000022F 83 FB 10 cmp ebx, 10h seg000:00000232 7D 2B jge short loc_25F seg000:00000232 seg000:00000234 B8 00 00 08 00 mov eax, 80000h seg000:00000239 8D 14 9D 08 0D 00 00 lea edx, ds:0D08h[ebx*4] seg000:00000240 8B 12 mov edx, [edx] seg000:00000242 66 89 D0 mov ax, dx seg000:00000245 66 BA 00 8E mov dx, 8E00h seg000:00000249 B9 21 00 00 00 mov ecx, 21h ; '!' seg000:0000024E 01 D9 add ecx, ebx seg000:00000250 8D 34 CD 28 01 00 00 lea esi, ds:128h[ecx*8] seg000:00000257 89 06 mov [esi], eax seg000:00000259 89 56 04 mov [esi+4], edx seg000:0000025C 43 inc ebx seg000:0000025D EB CF jmp short loc_22E seg000:0000025D seg000:0000025F ; --------------------------------------------------------------------------- seg000:0000025F seg000:0000025F loc_25F: ; CODE XREF: sub_200+32↑j seg000:0000025F ; sub_200+66↓j seg000:0000025F E8 04 00 00 00 call sub_268 seg000:0000025F seg000:00000264 CD 21 int 21h ; DOS - seg000:00000264 seg000:00000266 EB F7 jmp short loc_25F seg000:00000266 seg000:00000266 sub_200 endp
-
挨个分析:
-
seg000:0000028B sub_28B proc near ; CODE XREF: sub_200+E↑p seg000:0000028B BA FC 00 00 00 mov edx, 0FCh seg000:00000290 B8 00 00 08 00 mov eax, 80000h seg000:00000295 66 89 D0 mov ax, dx seg000:00000298 66 BA 00 8E mov dx, 8E00h seg000:0000029C 8D 3D 28 01 00 00 lea edi, loc_225+3 - (dword_74+8Ch)//地址是128h seg000:000002A2 B9 00 01 00 00 mov ecx, 100h seg000:000002A2 seg000:000002A7 seg000:000002A7 loc_2A7: ; CODE XREF: sub_28B+25↓j seg000:000002A7 89 07 mov [edi], eax seg000:000002A9 89 57 04 mov [edi+4], edx seg000:000002AC 83 C7 08 add edi, 8 seg000:000002AF 49 dec ecx seg000:000002B0 75 F5 jnz short loc_2A7 seg000:000002B0 seg000:000002B2 0F 01 1D 1C 01 00 00 lidt fword ptr ds:loc_218+4 seg000:000002B9 C3 retn seg000:000002B9 seg000:000002B9 sub_28B endp seg000:000002B9
-
seg000:00000283 sub_283 proc near ; CODE XREF: sub_200:loc_213↑p seg000:00000283 0F 01 15 22 01 00 00 lgdt fword ptr ds:loc_221+1 seg000:0000028A C3 retn seg000:0000028A seg000:0000028A sub_283 endp seg000:0000028A seg000:0000028B
-
上面两个就是将IDT和GDT的入口地址装入IDTR(GDTR)寄存器
-
再往下看:
-
给ds,es,fs,gs赋值,循环16次,loc_22E是将ds:0xD08开始的数据填充到ds:0x128,0x128是IDT表基地址,执行后中断21h到30h的的入口地址全部改变
-
sub_268:
-
seg000:00000268 sub_268 proc near ; CODE XREF: sub_200:loc_25F↑p seg000:00000268 8B 3D 78 0B 00 00 mov edi, dword ptr ds:unk_C78 seg000:0000026E 8D 3C BD 48 0D 00 00 lea edi, ds:0D48h[edi*4] seg000:00000275 8B 07 mov eax, [edi] seg000:00000277 A2 65 00 00 00 mov byte ptr ds:unk_165, al seg000:0000027C 8B 4F 04 mov ecx, [edi+4] seg000:0000027F 8B 47 08 mov eax, [edi+8] seg000:00000282 C3 retn seg000:00000282 seg000:00000282 sub_268 endp
-
这里的ds:unk_165就是 000264处的 int 21h
-
该段代码就是存储了虚拟机的指令,每条指令的长度为12字节,前四个字节为opcode,后面八个字节就是两个操作数,作为两个参数传入中断,中断作用相当于call,调用子程序就是handler
-
中断指令 的21h会一直改变,每次调用完子程序都会跳到EF8处,0B78处的值加3,从而执行0d48[edi*4]处的下一个中断
-
注:中断调用子程序地址按中断编号线性排列
-
seg000:00000EF8 8D 0D 78 0B 00 00 lea ecx, unk_B78 seg000:00000EFE 8B 01 mov eax, [ecx] seg000:00000F00 83 C0 03 add eax, 3 seg000:00000F03 89 01 mov [ecx], eax seg000:00000F05 CF iret seg000:00000F05 seg000:00000F05 ; -----------------------
-
下面逐个分析16个中断的意义:设0B64数组为buf,eax为a,ecx为c,0D48为code数组
-
seg000:00000D7C 8D 0C 8D 64 0B 00 00 lea ecx, ds:0B64h[ecx*4] seg000:00000D83 89 01 mov [ecx], eax seg000:00000D85 E9 6E 01 00 00 jmp loc_EF8 ; buf[c]=a; seg000:00000D85 seg000:00000D8A ; --------------------------------------------------------------------------- seg000:00000D8A 8D 04 85 64 0B 00 00 lea eax, ds:0B64h[eax*4] seg000:00000D91 8B 00 mov eax, [eax] seg000:00000D93 8D 0C 8D 64 0B 00 00 lea ecx, ds:0B64h[ecx*4] seg000:00000D9A 89 01 mov [ecx], eax seg000:00000D9C E9 57 01 00 00 jmp loc_EF8 ;buf[c]=buf[a] seg000:00000D9C seg000:00000DA1 ; --------------------------------------------------------------------------- seg000:00000DA1 8D 04 85 64 0B 00 00 lea eax, ds:0B64h[eax*4] seg000:00000DA8 8B 00 mov eax, [eax] seg000:00000DAA 8D 0C 8D 64 0B 00 00 lea ecx, ds:0B64h[ecx*4] seg000:00000DB1 8D 04 85 48 0D 00 00 lea eax, ds:0D48h[eax*4] seg000:00000DB8 8B 00 mov eax, [eax] seg000:00000DBA 89 01 mov [ecx], eax;buf[c]=code[buf[a]] seg000:00000DBC E9 37 01 00 00 jmp loc_EF8 seg000:00000DBC seg000:00000DC1 ; --------------------------------------------------------------------------- seg000:00000DC1 8D 04 85 64 0B 00 00 lea eax, ds:0B64h[eax*4] seg000:00000DC8 8B 00 mov eax, [eax] seg000:00000DCA 8D 0C 8D 64 0B 00 00 lea ecx, ds:0B64h[ecx*4] seg000:00000DD1 8B 09 mov ecx, [ecx] seg000:00000DD3 8D 0C 8D 48 0D 00 00 lea ecx, ds:0D48h[ecx*4] seg000:00000DDA 89 01 mov [ecx], eax seg000:00000DDC E9 17 01 00 00 jmp loc_EF8;code[buf[c]]=buf[a]; seg000:00000DDC seg000:00000DE1 ; --------------------------------------------------------------------------- seg000:00000DE1 8D 04 85 64 0B 00 00 lea eax, ds:0B64h[eax*4] seg000:00000DE8 8B 10 mov edx, [eax] seg000:00000DEA 8D 0C 8D 64 0B 00 00 lea ecx, ds:0B64h[ecx*4] seg000:00000DF1 8B 01 mov eax, [ecx] seg000:00000DF3 01 D0 add eax, edx seg000:00000DF5 89 01 mov [ecx], eax seg000:00000DF7 E9 FC 00 00 00 jmp loc_EF8;code[buf[c]]=buf[a]; seg000:00000DF7 seg000:00000DFC ; --------------------------------------------------------------------------- seg000:00000DFC 8D 04 85 64 0B 00 00 lea eax, ds:0B64h[eax*4] seg000:00000E03 8B 10 mov edx, [eax] seg000:00000E05 8D 0C 8D 64 0B 00 00 lea ecx, ds:0B64h[ecx*4] seg000:00000E0C 8B 01 mov eax, [ecx] seg000:00000E0E 29 D0 sub eax, edx seg000:00000E10 89 01 mov [ecx], eax seg000:00000E12 E9 E1 00 00 00 jmp loc_EF8 seg000:00000E12;buf[c]=buf[c]-buf[a]; seg000:00000E17 ; --------------------------------------------------------------------------- seg000:00000E17 8D 04 85 64 0B 00 00 lea eax, ds:0B64h[eax*4] seg000:00000E1E 8B 10 mov edx, [eax] seg000:00000E20 8D 0C 8D 64 0B 00 00 lea ecx, ds:0B64h[ecx*4] seg000:00000E27 8B 01 mov eax, [ecx] seg000:00000E29 31 D0 xor eax, edx seg000:00000E2B 89 01 mov [ecx], eax seg000:00000E2D E9 C6 00 00 00 jmp loc_EF8 seg000:00000E2D;buf[c]=buf[c]^buf[a]; seg000:00000E32 ; --------------------------------------------------------------------------- seg000:00000E32 8D 04 85 64 0B 00 00 lea eax, ds:0B64h[eax*4] seg000:00000E39 8B 00 mov eax, [eax] seg000:00000E3B 8D 14 8D 64 0B 00 00 lea edx, ds:0B64h[ecx*4] seg000:00000E42 88 C1 mov cl, al seg000:00000E44 8B 02 mov eax, [edx] seg000:00000E46 D3 E0 shl eax, cl seg000:00000E48 seg000:00000E48 loc_E48: seg000:00000E48 89 02 mov [edx], eax seg000:00000E4A E9 A9 00 00 00 jmp loc_EF8 seg000:00000E4A;buf[c]=buf[c]<<(buf[a]&0xFF); seg000:00000E4F ; --------------------------------------------------------------------------- seg000:00000E4F seg000:00000E4F loc_E4F: seg000:00000E4F 8D 04 85 64 0B 00 00 lea eax, ds:0B64h[eax*4] seg000:00000E56 8B 00 mov eax, [eax] seg000:00000E58 8D 14 8D 64 0B 00 00 lea edx, ds:0B64h[ecx*4] seg000:00000E5F 88 C1 mov cl, al seg000:00000E61 8B 02 mov eax, [edx] seg000:00000E63 D3 E8 shr eax, cl seg000:00000E65 89 02 mov [edx], eax seg000:00000E67 E9 8C 00 00 00 jmp loc_EF8 seg000:00000E67;buf[c]=buf[c]>>(buf[a]&0xFF); seg000:00000E6C ; --------------------------------------------------------------------------- seg000:00000E6C 8D 04 85 64 0B 00 00 lea eax, ds:0B64h[eax*4] seg000:00000E73 8B 00 mov eax, [eax] seg000:00000E75 8D 0C 8D 64 0B 00 00 lea ecx, ds:0B64h[ecx*4] seg000:00000E7C 8B 11 mov edx, [ecx] seg000:00000E7E 21 D0 and eax, edx seg000:00000E80 89 01 mov [ecx], eax seg000:00000E82 EB 74 jmp short loc_EF8 seg000:00000E82;buf[c]=buf[c]>>(buf[a]&0xFF); seg000:00000E84 ; --------------------------------------------------------------------------- seg000:00000E84 8D 04 8D 64 0B 00 00 lea eax, ds:0B64h[ecx*4] seg000:00000E8B 8B 00 mov eax, [eax] seg000:00000E8D 8D 0D 78 0B 00 00 lea ecx, unk_B78 seg000:00000E93 89 01 mov [ecx], eax seg000:00000E95 CF iret seg000:00000E95;ds:0x0b78=buf[c]; seg000:00000E96 ; --------------------------------------------------------------------------- seg000:00000E96 8D 04 85 64 0B 00 00 lea eax, ds:0B64h[eax*4] seg000:00000E9D 8B 00 mov eax, [eax] seg000:00000E9F 85 C0 test eax, eax seg000:00000EA1 75 55 jnz short loc_EF8 seg000:00000EA1 seg000:00000EA3 8D 04 8D 64 0B 00 00 lea eax, ds:0B64h[ecx*4] seg000:00000EAA 8B 00 mov eax, [eax] seg000:00000EAC 8D 0D 78 0B 00 00 lea ecx, unk_B78 seg000:00000EB2 89 01 mov [ecx], eax seg000:00000EB4 CF iret seg000:00000EB4;if {buf[a]==0} ds:0x0b78=buf[c]; seg000:00000EB5 ; --------------------------------------------------------------------------- seg000:00000EB5 8D 04 85 64 0B 00 00 lea eax, ds:0B64h[eax*4] seg000:00000EBC 8B 00 mov eax, [eax] seg000:00000EBE 85 C0 test eax, eax seg000:00000EC0 74 36 jz short loc_EF8 seg000:00000EC0 seg000:00000EC2 8D 04 8D 64 0B 00 00 lea eax, ds:0B64h[ecx*4] seg000:00000EC9 8B 00 mov eax, [eax] seg000:00000ECB 8D 0D 78 0B 00 00 lea ecx, unk_B78 seg000:00000ED1 89 01 mov [ecx], eax seg000:00000ED3 CF iret seg000:00000ED3;if{buf[a]!=0} ds:0x0b78=buf[c]; seg000:00000ED4 ; --------------------------------------------------------------------------- seg000:00000ED4 8D 05 94 0F 00 00 lea eax, unk_F94 seg000:00000EDA E8 0B F4 FF FF call sub_2EA seg000:00000EDA seg000:00000EDF F4 hlt;暂停; seg000:00000EE0 8D 05 A0 0F 00 00 lea eax, unk_FA0 seg000:00000EE6 E8 FF F3 FF FF call sub_2EA;正确 seg000:00000EE6 seg000:00000EEB 8D 05 AE 0F 00 00 lea eax, word_FAE seg000:00000EF1 E8 F4 F3 FF FF call sub_2EA;错误 seg000:00000EF1 seg000:00000EF6 F4 hlt
-
后面把数据dump出来(注意是DWORD类型数组)写脚本模拟虚拟机
-
data = [ 0x00000021, 0x00000000, 0x00000081, 0x00000027, 0x00000001, 0x00000001, 0x00000024, 0x00000001, 0x00000001, 0x00000023, 0x00000002, 0x00000000, 0x00000022, 0x00000003, 0x00000002, 0x00000021, 0x00000004, 0x00000008, 0x00000028, 0x00000003, 0x00000004, 0x00000027, 0x00000002, 0x00000003, 0x00000028, 0x00000003, 0x00000004, 0x00000027, 0x00000002, 0x00000003, 0x00000028, 0x00000003, 0x00000004, 0x00000027, 0x00000002, 0x00000003, 0x00000027, 0x00000003, 0x00000003, 0x00000023, 0x00000004, 0x00000003, 0x00000024, 0x00000003, 0x00000002, 0x00000027, 0x00000002, 0x00000004, 0x00000024, 0x00000000, 0x00000002, 0x00000021, 0x00000001, 0x00000001, 0x00000025, 0x00000000, 0x00000001, 0x00000022, 0x00000001, 0x00000000, 0x00000021, 0x00000002, 0x00000081, 0x00000026, 0x00000001, 0x00000002, 0x00000021, 0x00000002, 0x00000009, 0x00000026, 0x00000001, 0x00000002, 0x00000021, 0x00000002, 0x00000009, 0x0000002D, 0x00000002, 0x00000001, 0x00000021, 0x00000000, 0x00000081, 0x00000022, 0x00000001, 0x00000000, 0x00000021, 0x00000002, 0x00000009, 0x00000025, 0x00000001, 0x00000002, 0x00000023, 0x00000003, 0x00000000, 0x00000023, 0x00000004, 0x00000001, 0x00000026, 0x00000003, 0x00000004, 0x00000021, 0x00000004, 0x0000007E, 0x0000002D, 0x00000004, 0x00000003, 0x00000021, 0x00000003, 0x00000001, 0x00000025, 0x00000000, 0x00000003, 0x00000025, 0x00000001, 0x00000003, 0x00000026, 0x00000002, 0x00000003, 0x00000021, 0x00000004, 0x0000005A, 0x0000002D, 0x00000004, 0x00000002, 0x0000002F, 0x00000000, 0x00000000, 0x00000030, 0x00000000, 0x00000000 ] i = 0 while (i<=126): if data[i] == 0x21: print ("buf[%d]=%d" % (data[i+1], data[i+2])) if data[i] == 0x22: print ("buf[%d]=buf[%d]" % (data[i+1], data[i+2])) if data[i] == 0x23: print ("buf[%d]=code[buf[%d]]" % (data[i+1], data[i+2])) if data[i] == 0x24: print ("code[buf[%d]]=buf[%d]" % (data[i+1], data[i+2])) if data[i] == 0x25: print ("buf[%d]+=buf[%d]" % (data[i+1], data[i+2])) if data[i] == 0x26: print ("buf[%d]-=buf[%d]" % (data[i+1], data[i+2])) if data[i] == 0x27: print ("buf[%d]^=buf[%d]" % (data[i+1], data[i+2])) if data[i] == 0x28: print ("buf[%d]<<=buf[%d]" % (data[i+1], data[i+2])) if data[i] == 0x29: print ("buf[%d]>>=buf[%d]" % (data[i+1], data[i+2])) if data[i] == 0x2A: print ("buf[%d]&=buf[%d]" % (data[i+1], data[i+2])) if data[i] == 0x2B: print ("i =buf[%d]" % (data[i+1])) if data[i] == 0x2c: print ("if buf[%d]==0 i=buf[%d]" % (data[i+2], data[i+1])) if data[i] == 0x2d: print ("if buf[%d]!=0 i=buf[%d]" % (data[i+2], data[i+1])) if data[i] == 0x2e: print ("pause") if data[i] == 0x2f: print ("correct") if data[i] == 0x30: print ("wrong") i+=3
-
输出:
-
buf[0]=129 buf[1]^=buf[1] code[buf[1]]=buf[1] buf[2]=code[buf[0]] buf[3]=buf[2] buf[4]=8 buf[3]<<=buf[4] buf[2]^=buf[3] buf[3]<<=buf[4] buf[2]^=buf[3] buf[3]<<=buf[4] buf[2]^=buf[3] buf[3]^=buf[3] buf[4]=code[buf[3]] code[buf[3]]=buf[2] buf[2]^=buf[4] code[buf[0]]=buf[2] buf[1]=1 buf[0]+=buf[1] buf[1]=buf[0] buf[2]=129 buf[1]-=buf[2] buf[2]=9 buf[1]-=buf[2] buf[2]=9 if buf[1]!=0 i=buf[2] buf[0]=129 buf[1]=buf[0] buf[2]=9 buf[1]+=buf[2] buf[3]=code[buf[0]] buf[4]=code[buf[1]] buf[3]-=buf[4] buf[4]=126 if buf[3]!=0 i=buf[4] buf[3]=1 buf[0]+=buf[3] buf[1]+=buf[3] buf[2]-=buf[3] buf[4]=90 if buf[2]!=0 i=buf[4] correct wrong
-
代码一共循环9次执行指令code[i]=code[i] ^(code[i]<<8) ^ (code[i]<<16) ^(code[i]<<24) ^ code[i-1];之后再执行9次比较;buf[i]与buf[i+9]进行9次比较。
-
a=[0x57635565, 0x06530401, 0x1F494949, 0x5157071F, 0x575F4357, 0x57435E57, 0x4357020A, 0x575E035E,0x0f590000,0x0] for x in range (0,9): m4=a[x]&0xff m3=(a[x]&0xff00)>>8 m2=(a[x]&0xff0000)>>16 m1=(a[x]&0xff000000)>>24 p1=m4 p2=p1^m3 p3=p1^m2^p2 p4=p1^p2^p3^m1 flag=p1+(p2<<8)+(p3<<16)+(p4<<24) print(long_to_bytes(flag)) a[x+1]=a[x]^a[x+1]
-
我直接用longtobytes了
-
b'460e' b'aa5d' b'7a5-' b'11-2' b'9-9e' b'-002' b'9e88' b'08ef' b'faef'
-
调整顺序,这就是flag
-
后来发现:
-
0x61646238, 0x36353465, 0x6361352D, 0x31312D38, 0x612D3965, 0x2D316331, 0x39653838, 0x30386566, 0x66616566, 0x57635565, 0x06530401, 0x1F494949, 0x5157071F, 0x575F4357, 0x57435E57, 0x4357020A, 0x575E035E, 0x0F590000,
-
flag就是数据段中已经有的,算非预期嘛?(不过也还是要找到这个循环比较
-
总结:软盘分析,中断向量表,vm混淆
[2019Ciscn初赛] Strange int
发布于
2023-12-15
|
31分钟
|
5947字数
|
浏览量::
- 本文作者: Tanggerr
- 本文链接: https://Tanggerr.github.io/post/2019ciscn-chu-sai-strange-int/
- 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
0%
召唤看板娘
x
感谢您的支持,我会继续努力的!
扫码打赏,你说多少就多少