- 一个小木马脱壳 请虚拟机下调试 相关文件见附件 未知壳相当简单 但是典型 有stolen code和overlay 只是练习脱壳 所以没有分析木马
- 初次实战 一路F8
- 载入:
- 00410336 > $ 57 PUSH EDI
- 00410337 . 8BFC MOV EDI,ESP
- 00410339 . 83EC 26 SUB ESP,26
- 0041033C . C74424 0E 000>MOV DWORD PTR SS:[ESP+E],0
- 00410344 > C74424 06 FB6>MOV DWORD PTR SS:[ESP+6],DC8A65FB ;解密key
- 0041034C . C74424 02 000>MOV DWORD PTR SS:[ESP+2],0
- 00410354 . BE D5034100 MOV ESI,1.004103D5 ;解密起始地址
- 00410359 . 897424 12 MOV DWORD PTR SS:[ESP+12],ESI
- 0041035D > EB 00 JMP SHORT 1.0041035F
- 0041035F > BE 7A210000 MOV ESI,217A
- 00410364 . 03F7 ADD ESI,EDI
- 00410366 . 2BF4 SUB ESI,ESP ;esi + esp + (esp-26h) = esi + 26h
- 00410368 . 397424 0E CMP DWORD PTR SS:[ESP+E],ESI ;[esp+e]计数器
- 0041036C . 74 02 JE SHORT 1.00410370
- 0041036E . EB 0C JMP SHORT 1.0041037C
- 00410370 > 8B7424 12 MOV ESI,DWORD PTR SS:[ESP+12] ;[esp+e] == esi时 才开始解密
- 00410374 . 8A6424 06 MOV AH,BYTE PTR SS:[ESP+6]
- 00410378 . 2826 SUB BYTE PTR DS:[ESI],AH
- 0041037A . EB 00 JMP SHORT 1.0041037C
- 0041037C > 834424 12 01 ADD DWORD PTR SS:[ESP+12],1
- 00410381 . C16C24 06 02 SHR DWORD PTR SS:[ESP+6],2
- 00410386 . C16C24 06 02 SHR DWORD PTR SS:[ESP+6],2
- 0041038B . C16C24 06 02 SHR DWORD PTR SS:[ESP+6],2
- 00410390 . C16C24 06 02 SHR DWORD PTR SS:[ESP+6],2 ;右移8位 即右移一个字节
- 00410395 . 834424 02 01 ADD DWORD PTR SS:[ESP+2],1
- 0041039A . 837C24 02 04 CMP DWORD PTR SS:[ESP+2],4
- 0041039F . 75 10 JNZ SHORT 1.004103B1
- 004103A1 . C74424 06 FB6>MOV DWORD PTR SS:[ESP+6],DC8A65FB
- 004103A9 . C74424 02 000>MOV DWORD PTR SS:[ESP+2],0
- 004103B1 > BE 98064100 MOV ESI,1.00410698 ;解密终止地址
- 004103B6 . 397424 12 CMP DWORD PTR SS:[ESP+12],ESI
- 004103BA .^ 72 A1 JB SHORT 1.0041035D
- 004103BC . FF4424 0E INC DWORD PTR SS:[ESP+E]
- 004103C0 . 817C24 0E 332>CMP DWORD PTR SS:[ESP+E],2333
- 004103C8 .^ 0F86 76FFFFFF JBE 1.00410344
- //整个解密过程 简单但是干扰性极大 [esp+e]为21A0时解密才开始 解密过程的key为DC8A65FB 变换过程 循环右移一个字节
- 00410407 |. 33C0 XOR EAX,EAX
- 00410409 |. 8B0424 MOV EAX,DWORD PTR SS:[ESP] ;kernel里的一个地址送eax
- 0041040C |. 66:33C0 XOR AX,AX
- 0041040F |. 68 FFFF0000 PUSH 0FFFF ;函数名HASH值入栈
- 00410414 |. 68 B674755D PUSH 5D7574B6 ;GetProcAddress
- 00410419 |. 68 2207E471 PUSH 71E40722 ;LoadLibraryA
- 0041041E |. 68 80EFF815 PUSH 15F8EF80 ;VirtualProtect
- 00410423 |. 68 EC5863D6 PUSH D66358EC ;ExitProcess
- 00410428 |. 8BFC MOV EDI,ESP ;EDI 用来定位 堆栈
- 0041042A |> 66:8138 4D5A /CMP WORD PTR DS:[EAX],5A4D ;PE
- 0041042F |. 75 13 |JNZ SHORT 1.00410444
- 00410431 |. 8B50 3C |MOV EDX,DWORD PTR DS:[EAX+3C]
- 00410434 |. 81FA 00100000 |CMP EDX,1000
- 0041043A |. 77 08 |JA SHORT 1.00410444
- 0041043C |. 66:813C10 504>|CMP WORD PTR DS:[EAX+EDX],4550 ;MZ
- 00410442 |. 74 07 |JE SHORT 1.0041044B
- 00410444 |> 2D 00000100 |SUB EAX,10000 ; UNICODE "ALLUSERSPROFILE=C:/Documents and Settings/All Users"
- 00410449 |.^ EB DF /JMP SHORT 1.0041042A
- //寻找kernel 基址
- 0041044B |> /50 PUSH EAX ; kernel32.7C800000
- 0041044C |. 8B7410 78 MOV ESI,DWORD PTR DS:[EAX+EDX+78] ; 定位到DataDirectory[0].VirtualAddress
- 00410450 |. 03F0 ADD ESI,EAX ; 定位到导出表
- 00410452 |. 83C6 18 ADD ESI,18 ;IMAGE_EXPORT_DIRECTORY.NumberOfNames
- 00410455 |. 93 XCHG EAX,EBX
- 00410456 |. AD LODS DWORD PTR DS:[ESI]
- 00410457 |. 50 PUSH EAX ;IMAGE_EXPORT_DIRECTORY.NumberOfNames入栈
- 00410458 |. AD LODS DWORD PTR DS:[ESI]
- 00410459 |. 50 PUSH EAX ;IMAGE_EXPORT_DIRECTORY.AddressOfFunctions入栈
- 0041045A |. AD LODS DWORD PTR DS:[ESI]
- 0041045B |. 50 PUSH EAX ;IMAGE_EXPORT_DIRECTORY.AddressOfNames入栈
- 0041045C |. 03C3 ADD EAX,EBX
- 0041045E |. 50 PUSH EAX ;IMAGE_EXPORT_DIRECTORY.AddressOfNames+ImageBase入栈
- 0041045F |. AD LODS DWORD PTR DS:[ESI]
- 00410460 |. 50 PUSH EAX ;IMAGE_EXPORT_DIRECTORY.AddressOfNameOrdinals入栈
- 00410461 |. 8BEC MOV EBP,ESP ;EBP指向IMAGE_EXPORT_DIRECTORY.AddressOfNameOrdinals
- 00410463 |> 8B4D 10 /MOV ECX,DWORD PTR SS:[EBP+10] ;IMAGE_EXPORT_DIRECTORY.NumberOfNames
- 00410466 |. 33D2 |XOR EDX,EDX
- 00410468 |> 8B75 04 |/MOV ESI,DWORD PTR SS:[EBP+4] ;IMAGE_EXPORT_DIRECTORY.AddressOfNames+ImageBase
- 0041046B |. 8B36 ||MOV ESI,DWORD PTR DS:[ESI] ;ESI 为 函数名的起始地址RVA
- 0041046D |. 03F3 ||ADD ESI,EBX ;得到函数名地址VA
- 0041046F |. 33C0 ||XOR EAX,EAX
- 00410471 |. 50 ||PUSH EAX
- 00410472 |> C1C8 07 ||/ROR EAX,7
- 00410475 |. 310424 |||XOR DWORD PTR SS:[ESP],EAX
- 00410478 |. AC |||LODS BYTE PTR DS:[ESI]
- 00410479 |. 84C0 |||TEST AL,AL
- 0041047B |.^ 75 F5 ||/JNZ SHORT 1.00410472 ;函数名HASH
- 0041047D |. 58 ||POP EAX
- 0041047E |. 57 ||PUSH EDI
- 0041047F |> 813F FFFF0000 ||/CMP DWORD PTR DS:[EDI],0FFFF ;函数是否 地址都找到 找到就跳
- 00410485 |. 74 09 |||JE SHORT 1.00410490
- 00410487 |. 3B07 |||CMP EAX,DWORD PTR DS:[EDI] ;比较函数名HASH值
- 00410489 |. 74 0F |||JE SHORT 1.0041049A
- 0041048B |. 83C7 04 |||ADD EDI,4
- 0041048E |.^ EB EF ||/JMP SHORT 1.0041047F
- 00410490 |> 5F ||POP EDI
- 00410491 |. 8345 04 04 ||ADD DWORD PTR SS:[EBP+4],4 ;移到下一个函数名起始地址
- 00410495 |. 42 ||INC EDX
- 00410496 |.^ E2 D0 |/LOOPD SHORT 1.00410468
- 00410498 |. EB 2C |JMP SHORT 1.004104C6
- 0041049A |> D1E2 |SHL EDX,1
- 0041049C |. 8B4D 00 |MOV ECX,DWORD PTR SS:[EBP] ;IMAGE_EXPORT_DIRECTORY.AddressOfNameOrdinals
- 0041049F |. 03CB |ADD ECX,EBX ;IMAGE_EXPORT_DIRECTORY.AddressOfNameOrdinals+IMAGEBASE
- 004104A1 |. 03CA |ADD ECX,EDX ;得到特定函数 序号地址
- 004104A3 |. 8B09 |MOV ECX,DWORD PTR DS:[ECX] ;得到函数序号
- 004104A5 |. 81E1 FFFF0000 |AND ECX,0FFFF
- 004104AB |. 8B55 0C |MOV EDX,DWORD PTR SS:[EBP+C] ;IMAGE_EXPORT_DIRECTORY.AddressOfFunctions
- 004104AE |. 03D3 |ADD EDX,EBX ;IMAGE_EXPORT_DIRECTORY.AddressOfFunctions+IAMGEBASE
- 004104B0 |. C1E1 02 |SHL ECX,2
- 004104B3 |. 03D1 |ADD EDX,ECX
- 004104B5 |. 8B12 |MOV EDX,DWORD PTR DS:[EDX]
- 004104B7 |. 03D3 |ADD EDX,EBX ;得到函数VA
- 004104B9 |. 8917 |MOV DWORD PTR DS:[EDI],EDX ;存放函数地址
- 004104BB |. 8B4D 08 |MOV ECX,DWORD PTR SS:[EBP+8]
- 004104BE |. 03CB |ADD ECX,EBX
- 004104C0 |. 894D 04 |MOV DWORD PTR SS:[EBP+4],ECX
- 004104C3 |. 5F |POP EDI
- 004104C4 |.^ EB 9D /JMP SHORT 1.00410463
- //想起failwest的shellcode。。。。。
- 004104C6 |> /83EF 04 SUB EDI,4
- 004104C9 |. 8BE7 MOV ESP,EDI
- 004104CB |. 8B5C24 08 MOV EBX,DWORD PTR SS:[ESP+8]
- 004104CF |. 8BFC MOV EDI,ESP
- 004104D1 |. 83EF 04 SUB EDI,4
- 004104D4 |. 57 PUSH EDI
- 004104D5 |. 6A 40 PUSH 40 ;PAGE_EXECUTE_READWRITE
- 004104D7 |. 68 00100000 PUSH 1000
- 004104DC |. 68 00004000 PUSH 1.00400000
- 004104E1 |. FFD3 CALL EBX ; VirtualProtect修改PE头属性为可读可写可执行
- 004104E3 |. BF 00004000 MOV EDI,1.00400000 ;IMAGEBASE
- 004104E8 |. 037F 3C ADD EDI,DWORD PTR DS:[EDI+3C] ;IMAGE_NT_HEADER
- 004104EB |. C787 A0000000>MOV DWORD PTR DS:[EDI+A0],12000 ;重定位表IMAGE_DIRECTORY_ENTRY_BASERELOC.VirtualAddress
- 004104F5 |. C787 A4000000>MOV DWORD PTR DS:[EDI+A4],11E4 ;IMAGE_DIRECTORY_ENTRY_BASERELOC.Size
- 004104FF |. C787 80000000>MOV DWORD PTR DS:[EDI+80],0 ;IMAGE_DIRECTORY_ENTRY_IMPORT.VirtualAddress清空了导入表偏移
- 00410509 |. C787 84000000>MOV DWORD PTR DS:[EDI+84],0 ;IMAGE_DIRECTORY_ENTRY_IMPORT.Size
- 00410513 |. 8BD7 MOV EDX,EDI ;IMAGE_NT_HEADER
- 00410515 |. 83C2 18 ADD EDX,18 ;IMAGE_OPTIONAL_HEADER32
- 00410518 |. 33C9 XOR ECX,ECX
- 0041051A |. 66:8B4F 14 MOV CX,WORD PTR DS:[EDI+14] ;SizeOfOptionalHeader
- 0041051E |. 03D1 ADD EDX,ECX ;定位到节表IMAGE_SECTION_HEADER
- 00410520 |. 33C9 XOR ECX,ECX
- 00410522 |> 8B72 0C /MOV ESI,DWORD PTR DS:[EDX+C] ;IMAGE_SECTION_HEADER.VirtualAddress
- 00410525 |. 81C6 00004000 |ADD ESI,1.00400000 ;IMAGE_SECTION_HEADER.VirtualAddress+IMAGEBASE
- 0041052B |. 60 |PUSHAD
- 0041052C |. 8BFC |MOV EDI,ESP
- 0041052E |. 83EF 04 |SUB EDI,4
- 00410531 |. 57 |PUSH EDI
- 00410532 |. 6A 40 |PUSH 40
- 00410534 |. FF72 08 |PUSH DWORD PTR DS:[EDX+8] ;IMAGE_SECTION_HEADER.VirtualSize
- 00410537 |. 56 |PUSH ESI
- 00410538 |. FFD3 |CALL EBX ;VirtualProtect
- 0041053A |. 61 |POPAD
- 0041053B |. 83C2 28 |ADD EDX,28
- 0041053E |. 41 |INC ECX
- 0041053F |. 81F9 03000000 |CMP ECX,3
- 00410545 |.^ 72 DB /JB SHORT 1.00410522 ;将PE文件前3个节属性变为可读可写可执行
- 00410547 |. 83EA 28 SUB EDX,28 ;定位到第3个节的节表
- 0041054A |. 8B42 0C MOV EAX,DWORD PTR DS:[EDX+C] ;IMAGE_SECTION_HEADER.VirtualAddress
- 0041054D |. 0342 10 ADD EAX,DWORD PTR DS:[EDX+10] ;+ IMAGE_SECTION_HEADER.SizeOfRawData
- 00410550 |. 05 00004000 ADD EAX,1.00400000 ;定位到节空隙
- 00410555 |. 83C0 64 ADD EAX,64
- 00410558 |. 60 PUSHAD
- 00410559 |. 8BF8 MOV EDI,EAX
- 0041055B |. BE D5034100 MOV ESI,1.004103D5 ;首次解密的起始地址
- 00410560 |. B9 98064100 MOV ECX,1.00410698 ;首次解密的终止地址
- 00410565 |. 2BCE SUB ECX,ESI
- 00410567 |. F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
- ;将壳代码复制到节表间隙中去 想写插入型病毒的可以参考这里怎样定位的
- 00410569 |. 61 POPAD
- 0041056A |. 68 FB658ADC PUSH DC8A65FB
- 0041056F |. FFE0 JMP EAX ;跳
- 00413667 . B9 FB658ADC MOV ECX,DC8A65FB ;注意上面入栈的 再看看这里 该壳有多种变形壳 但是都是通过 比较一个DWORD 来确定 运行流程
- 0041366C . 3B0C24 CMP ECX,DWORD PTR SS:[ESP]
- 0041366F . 0F84 8B010000 JE 1.00413800 ;跳到壳的第二部分
- 00413675 . B8 00000000 MOV EAX,0
- 00413800 > /5E POP ESI
- 00413801 . 05 98064100 ADD EAX,1.00410698
- 00413806 . 2D D5034100 SUB EAX,1.004103D5 ;重定位壳代码的 结束地址
- 0041380B . 8BD8 MOV EBX,EAX
- 0041380D . 33C0 XOR EAX,EAX
- 0041380F . B8 03000000 MOV EAX,3
- 00413814 . 48 DEC EAX
- 00413815 . 6BC0 28 IMUL EAX,EAX,28
- 00413818 . 2BD0 SUB EDX,EAX ;定位到第1个节的IMAGE_SECTION_HEADER
- 0041381A . 33C9 XOR ECX,ECX
- 0041381C > 8B72 0C MOV ESI,DWORD PTR DS:[EDX+C] ;IMAGE_SECTION_HEADER[0].VirtualAddress
- 0041381F . 81C6 00004000 ADD ESI,1.00400000 ;+IMAGEBASE
- 00413825 . 33C0 XOR EAX,EAX
- 00413827 . 8A06 MOV AL,BYTE PTR DS:[ESI] ;每个节的开始 都有一个结构
- 00413829 . 03F0 ADD ESI,EAX
- 0041382B . 60 PUSHAD
- 0041382C . 8BFB MOV EDI,EBX
- 0041382E . E8 1F000000 CALL 1.00413852 ;解压CALL跟进去看看
- {
- 00413852 /$ 60 PUSHAD
- 00413853 |. BB D218CF1F MOV EBX,1FCF18D2
- 00413858 |. B9 00000000 MOV ECX,0
- 0041385D |. BA 00000000 MOV EDX,0
- 00413862 |> 281E /SUB BYTE PTR DS:[ESI],BL
- 00413864 |. C1EB 08 |SHR EBX,8
- 00413867 |. 41 |INC ECX
- 00413868 |. 83F9 04 |CMP ECX,4
- 0041386B |. 75 0A |JNZ SHORT 1.00413877
- 0041386D |. BB D218CF1F |MOV EBX,1FCF18D2
- 00413872 |. B9 00000000 |MOV ECX,0
- 00413877 |> 46 |INC ESI
- 00413878 |. 42 |INC EDX
- 00413879 |. 83FA 08 |CMP EDX,8
- 0041387C |.^ 7C E4 |JL SHORT 1.00413862
- 0041387E |. 7F 05 |JG SHORT 1.00413885 ;EDX为8时才 解密
- 00413880 |. 8B46 FC |MOV EAX,DWORD PTR DS:[ESI-4] ;解密后的[ESI-4]代表 需解压的代码 终止地址
- 00413883 |. 03C6 |ADD EAX,ESI
- 00413885 |> 3BF0 |CMP ESI,EAX
- 00413887 |.^ 7C D9 /JL SHORT 1.00413862
- 00413889 |. 61 POPAD
- //下面是解压过程 代码不贴了
- }
- 每个节的第1个字节 代表需解密的代码在节中偏移,解密后的代码的第2个DWORD值代表需解压的代码的大小
- 导入表在第3个节中 第3次解压将导入表破坏
- 00413833 . 8B0E MOV ECX,DWORD PTR DS:[ESI]
- 00413835 . 8BFE MOV EDI,ESI
- 00413837 . 2BF8 SUB EDI,EAX
- 00413839 . 8BF3 MOV ESI,EBX
- 0041383B . F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI];将解压后的代码复制回原地
- 0041383D . 61 POPAD
- 0041383E . 83C2 28 ADD EDX,28
- 00413841 . 41 INC ECX
- 00413842 . 81F9 03000000 CMP ECX,3
- 00413848 .^ 72 D2 JB SHORT 1.0041381C ;循环解压3个节
- 0041384A . B8 2D704000 MOV EAX,1.0040702D
- 0041384F . FFD0 CALL EAX ;进入OEP
- 00413851 . C3 RETN
- 简便方法:该壳 在最后解压3个节 并破坏原IAT 所以在原IAT 下硬件写入断点 就可停在0041383B 往下再走几步就到
- OEP了
- 修复IAT:整个壳 虽然清0了导入表偏移并破坏了导入表结构 但是该导入表是伪导入表 无论是壳 还是木马本身都跟该导入表中函数无关 dump后 importfix 检测到导入表但是无导入函数 直接运行后错误 所以仔细跟了下 是堆栈引起的 写了个脚本修复了下 运行后 dump 可以直接运行
- 脚本:
- var iataddress
- var mem
- var xxx
- var org_esp
- var oep
- var yyy
- gmi eip, IDATATABLE
- mov iataddress, $RESULT
- bphws iataddress, "w"
- run
- bphwcall
- findop eip, #ffd0#
- bp $RESULT
- run
- bc eip
- sti
- msg "到达oep,开始修补堆栈,修补后会改变OEP"
- mov oep, eip
- alloc 1000
- mov mem, $RESULT
- mov xxx, mem
- mov org_esp, esp
- @continue:
- add esp, 4
- cmp [esp], 0000ffff
- jnz @continue
- @next:
- mov [xxx], #68#,1
- inc xxx
- mov [xxx], [esp]
- sub esp,4
- add xxx,4
- cmp esp, org_esp
- jae @next
- mov [xxx], #ff25#, 2
- add xxx, 2
- mov [xxx], iataddress
- add xxx, 4
- sub xxx, mem
- mov [iataddress], oep
- add iataddress, 4
- mov eip, iataddress
- mov yyy, mem
- @orz:
- cmp xxx, 0
- je @exit
- mov [iataddress], [yyy], 1
- inc iataddress
- inc yyy
- dec xxx
- jmp @orz
- @exit:
- msg "修补完成,可以dump"
- free mem
- ret
- overlay处理:直接把原文件的overlay贴到 脱壳后的文件末尾就可以了
- 注意下:
- 1:我的虚拟机里XP版本过老 木马运行后 系统崩溃
- 可能是XP版本问题,换了个新版本的XP 运行正常 但是因为新版本的XP 没有弄测试
- 环境 所以不能肯定
- 2:在某个系统下调试 就不要换其它系统,修复堆栈里存放的函数地址 是直接从堆栈中读取的而不是 自己写动态获取过程得到的 所以 肯定不能跨系统版本运行 脚本运行过程中 会有个断点下在数据段的警告 确定就可以了
- 3:木马有危险,切记虚拟机下调试 稍微看了下 没有新技术 以后有时间再仔细分析 字符串都是加密的 不停的拷贝自身。。
- 附件下载:http://bbs.pediy.com/showthread.php?t=79532