目标:FSCapture7.9(
www.faststone.org)
工具:OD2.1 + OllyDumpEx + Detect it easy 0.95 + ImpREC 1.7e
环境:Windows 7 SP1 64bits En
说明:温故只新,加深理解,希望自己知其然还要知其所以然(所以这篇不用ESP定律等等方法,也是鼓励自己在看雪上写文章。)
第一步:查壳;简单不多说,直接上图。
下面以管理员方式运行OD,加载FSCapture.exe,出现下面提示框,
点击“否”,否则OD会自动到达OEP,等待一会之后,OD到达壳的OEP(我们要找加壳之前软件的OEP),由于UPX壳简单,所以下面简单列出壳的行为(注释出了壳的几个阶段),具体细节可以自己分析或者一起讨论。
Address Hex dump Command Comments
008867C0 /$ 60 PUSHAD
008867C1 |. BE 00E07300 MOV ESI,0073E000 ; UPX1's Virtual Address
008867C6 |. 8DBE 0030CCFF LEA EDI,[ESI+FFCC3000] ; UPX1's Virtual Address + (-UPX0's Virual Size)
008867CC |. 57 PUSH EDI ; UPX0's Virtual Address
008867CD |. 83CD FF OR EBP,FFFFFFFF
008867D0 |. EB 10 JMP SHORT 008867E2
008867D2 | 90 NOP
008867D3 | 90 NOP
008867D4 | 90 NOP
008867D5 | 90 NOP
008867D6 | 90 NOP
008867D7 | 90 NOP
008867D8 |> 8A06 MOV AL,BYTE PTR DS:[ESI] ; Uncompress {
008867DA |. 46 INC ESI
008867DB |. 8807 MOV BYTE PTR DS:[EDI],AL
008867DD |. 47 INC EDI
008867DE |> 01DB ADD EBX,EBX
008867E0 |. 75 07 JNZ SHORT 008867E9
008867E2 |> 8B1E MOV EBX,DWORD PTR DS:[ESI]
008867E4 |. 83EE FC SUB ESI,-4
008867E7 |. 11DB ADC EBX,EBX
008867E9 |>^ 72 ED JB SHORT 008867D8
008867EB |. B8 01000000 MOV EAX,1
008867F0 |> 01DB /ADD EBX,EBX
008867F2 |. 75 07 |JNZ SHORT 008867FB
008867F4 |. 8B1E |MOV EBX,DWORD PTR DS:[ESI]
008867F6 |. 83EE FC |SUB ESI,-4
008867F9 |. 11DB |ADC EBX,EBX
008867FB |> 11C0 |ADC EAX,EAX
008867FD |. 01DB |ADD EBX,EBX
008867FF |. 73 0B |JAE SHORT 0088680C
00886801 |. 75 28 |JNZ SHORT 0088682B
00886803 |. 8B1E |MOV EBX,DWORD PTR DS:[ESI]
00886805 |. 83EE FC |SUB ESI,-4
00886808 |. 11DB |ADC EBX,EBX
0088680A |. 72 1F |JB SHORT 0088682B
0088680C |> 48 |DEC EAX
0088680D |. 01DB |ADD EBX,EBX
0088680F |. 75 07 |JNZ SHORT 00886818
00886811 |. 8B1E |MOV EBX,DWORD PTR DS:[ESI]
00886813 |. 83EE FC |SUB ESI,-4
00886816 |. 11DB |ADC EBX,EBX
00886818 |> 11C0 |ADC EAX,EAX
0088681A |.^ EB D4 \JMP SHORT 008867F0
0088681C |> 01DB ADD EBX,EBX
0088681E |. 75 07 JNZ SHORT 00886827
00886820 |. 8B1E MOV EBX,DWORD PTR DS:[ESI]
00886822 |. 83EE FC SUB ESI,-4
00886825 |. 11DB ADC EBX,EBX
00886827 |> 11C9 ADC ECX,ECX
00886829 |. EB 52 JMP SHORT 0088687D
0088682B |> 31C9 XOR ECX,ECX ; Switch (cases 0..2, 2 exits)
0088682D |. 83E8 03 SUB EAX,3
00886830 |. 72 11 JB SHORT 00886843
00886832 |. C1E0 08 SHL EAX,8 ; Default case of switch FSCapture.88682B
00886835 |. 8A06 MOV AL,BYTE PTR DS:[ESI]
00886837 |. 46 INC ESI
00886838 |. 83F0 FF XOR EAX,FFFFFFFF
0088683B |. 74 75 JZ SHORT 008868B2
0088683D |. D1F8 SAR EAX,1
0088683F |. 89C5 MOV EBP,EAX
00886841 |. EB 0B JMP SHORT 0088684E
00886843 |> 01DB ADD EBX,EBX ; Cases 0, 1, 2 of switch FSCapture.88682B
00886845 |. 75 07 JNZ SHORT 0088684E
00886847 |. 8B1E MOV EBX,DWORD PTR DS:[ESI]
00886849 |. 83EE FC SUB ESI,-4
0088684C |. 11DB ADC EBX,EBX
0088684E |>^ 72 CC JB SHORT 0088681C
00886850 |. 41 INC ECX
00886851 |. 01DB ADD EBX,EBX
00886853 |. 75 07 JNZ SHORT 0088685C
00886855 |. 8B1E MOV EBX,DWORD PTR DS:[ESI]
00886857 |. 83EE FC SUB ESI,-4
0088685A |. 11DB ADC EBX,EBX
0088685C |>^ 72 BE JB SHORT 0088681C
0088685E |> 01DB /ADD EBX,EBX
00886860 |. 75 07 |JNZ SHORT 00886869
00886862 |. 8B1E |MOV EBX,DWORD PTR DS:[ESI]
00886864 |. 83EE FC |SUB ESI,-4
00886867 |. 11DB |ADC EBX,EBX
00886869 |> 11C9 |ADC ECX,ECX
0088686B |. 01DB |ADD EBX,EBX
0088686D |.^ 73 EF |JAE SHORT 0088685E
0088686F |. 75 09 |JNZ SHORT 0088687A
00886871 |. 8B1E |MOV EBX,DWORD PTR DS:[ESI]
00886873 |. 83EE FC |SUB ESI,-4
00886876 |. 11DB |ADC EBX,EBX
00886878 |.^ 73 E4 \JAE SHORT 0088685E
0088687A |> 83C1 02 ADD ECX,2
0088687D |> 81FD 00FBFFFF CMP EBP,-500
00886883 |. 83D1 02 ADC ECX,2
00886886 |. 8D142F LEA EDX,[EBP+EDI]
00886889 |. 83FD FC CMP EBP,-4
0088688C |. 76 0E JBE SHORT 0088689C
0088688E |> 8A02 /MOV AL,BYTE PTR DS:[EDX]
00886890 |. 42 |INC EDX
00886891 |. 8807 |MOV BYTE PTR DS:[EDI],AL
00886893 |. 47 |INC EDI
00886894 |. 49 |DEC ECX
00886895 |.^ 75 F7 \JNZ SHORT 0088688E
00886897 |.^ E9 42FFFFFF JMP 008867DE
0088689C |> 8B02 /MOV EAX,DWORD PTR DS:[EDX]
0088689E |. 83C2 04 |ADD EDX,4
008868A1 |. 8907 |MOV DWORD PTR DS:[EDI],EAX
008868A3 |. 83C7 04 |ADD EDI,4
008868A6 |. 83E9 04 |SUB ECX,4
008868A9 |.^ 77 F1 \JA SHORT 0088689C
008868AB |. 01CF ADD EDI,ECX
008868AD |.^ E9 2CFFFFFF JMP 008867DE ; Uncompress }
008868B2 |> 5E POP ESI ; Address Relocation {
008868B3 |. 89F7 MOV EDI,ESI
008868B5 |. B9 83690100 MOV ECX,16983
008868BA |> 8A07 MOV AL,BYTE PTR DS:[EDI]
008868BC |. 47 INC EDI
008868BD |. 2C E8 SUB AL,0E8
008868BF |> 3C 01 /CMP AL,1
008868C1 |.^ 77 F7 |JA SHORT 008868BA
008868C3 |. 803F 82 |CMP BYTE PTR DS:[EDI],82
008868C6 |.^ 75 F2 |JNE SHORT 008868BA
008868C8 |. 8B07 |MOV EAX,DWORD PTR DS:[EDI]
008868CA |. 8A5F 04 |MOV BL,BYTE PTR DS:[EDI+4]
008868CD |. 66:C1E8 08 |SHR AX,8
008868D1 |. C1C0 10 |ROL EAX,10
008868D4 |. 86C4 |XCHG AH,AL
008868D6 |. 29F8 |SUB EAX,EDI
008868D8 |. 80EB E8 |SUB BL,0E8
008868DB |. 01F0 |ADD EAX,ESI
008868DD |. 8907 |MOV DWORD PTR DS:[EDI],EAX
008868DF |. 83C7 05 |ADD EDI,5
008868E2 |. 88D8 |MOV AL,BL
008868E4 |.^ E2 D9 \LOOP SHORT 008868BF ; Address Relocation }
008868E6 |. 8DBE 00204800 LEA EDI,[ESI+482000] ; Deal with IAT(recovering by upx's own struct)
008868EC |> 8B07 MOV EAX,DWORD PTR DS:[EDI] ; {
008868EE |. 09C0 OR EAX,EAX
008868F0 |. 74 3C JZ SHORT 0088692E
008868F2 |. 8B5F 04 MOV EBX,DWORD PTR DS:[EDI+4]
008868F5 |. 8D8430 A40C49 LEA EAX,[ESI+EAX+490CA4]
008868FC |. 01F3 ADD EBX,ESI
008868FE |. 50 PUSH EAX
008868FF |. 83C7 08 ADD EDI,8
00886902 |. FF96 E40D4900 CALL DWORD PTR DS:[ESI+490DE4]
00886908 |. 95 XCHG EAX,EBP
00886909 |> 8A07 /MOV AL,BYTE PTR DS:[EDI]
0088690B |. 47 |INC EDI
0088690C |. 08C0 |OR AL,AL
0088690E |.^ 74 DC |JZ SHORT 008868EC
00886910 |. 89F9 |MOV ECX,EDI
00886912 |. 57 |PUSH EDI
00886913 |. 48 |DEC EAX
00886914 |. F2:AE |REPNE SCAS BYTE PTR ES:[EDI]
00886916 |. 55 |PUSH EBP
00886917 |. FF96 E80D4900 |CALL DWORD PTR DS:[ESI+490DE8]
0088691D |. 09C0 |OR EAX,EAX
0088691F |. 74 07 |JZ SHORT 00886928
00886921 |. 8903 |MOV DWORD PTR DS:[EBX],EAX
00886923 |. 83C3 04 |ADD EBX,4
00886926 |.^ EB E1 \JMP SHORT 00886909 ; Deal with IAT }
00886928 |> FF96 F80D4900 CALL DWORD PTR DS:[ESI+490DF8]
0088692E |> 8BAE EC0D4900 MOV EBP,DWORD PTR DS:[ESI+490DEC] ; Address of kernel32.VirtualProtect
00886934 |. 8DBE 00F0FFFF LEA EDI,[ESI-1000]
0088693A |. BB 00100000 MOV EBX,1000
0088693F |. 50 PUSH EAX
00886940 |. 54 PUSH ESP
00886941 |. 6A 04 PUSH 4
00886943 |. 53 PUSH EBX
00886944 |. 57 PUSH EDI
00886945 |. FFD5 CALL EBP ; call kernel32.VirtualProtect
00886947 |. 8D87 1F020000 LEA EAX,[EDI+21F]
0088694D |. 8020 7F AND BYTE PTR DS:[EAX],7F
00886950 |. 8060 28 7F AND BYTE PTR DS:[EAX+28],7F
00886954 |. 58 POP EAX
00886955 |. 50 PUSH EAX
00886956 |. 54 PUSH ESP
00886957 |. 50 PUSH EAX
00886958 |. 53 PUSH EBX
00886959 |. 57 PUSH EDI
0088695A |. FFD5 CALL EBP ; call kernel32.VirtualProtect
0088695C |. 58 POP EAX
0088695D |. 61 POPAD ; almost finished !!!
0088695E |. 8D4424 80 LEA EAX,[ESP-80]
00886962 |> 6A 00 /PUSH 0 ; fix stack {
00886964 |. 39C4 |CMP ESP,EAX
00886966 |.^ 75 FA \JNE SHORT 00886962
00886968 |. 83EC 80 SUB ESP,-80 ; fix stack }
0088696B \.^ E9 0428E9FF JMP 00719174 ; Jmp to original oep
00886970 /. 88698800 DD 00886988 ; StartAddressOfRawData = FSCapture.886988
00886974 |. A4698800 DD 008869A4 ; EndAddressOfRawData = FSCapture.8869A4
00886978 |. 10D77200 DD <TLSindex> ; AddressOfIndex = FSCapture.<TLSindex>
0088697C |. 00000000 DD 00000000 ; AddressOfCallBacks = 0
00886980 |. 00000000 DD 00000000 ; SizeOfZeroFill = 0
00886984 \. 00000000 DD 00000000 ; Characteristics = 0
这就是完整的壳解压及相关处理过程,包括解压、地址重定位、填充IAT、恢复PE头和区块属性。我已经注释了到达OEP的地方了。下面在OEP处按下F4吧。此时UPX已经做完了所有它应该做的事情了。现在右键dump(OllyDumpEx插件的功能),来到如下界面:
点击“Get EIP as OEP”(或者自己手动填写),(注意2处,我遇到过变种UPX,脱壳修复后这里需要修改才可以运行的程序)。点击Dump,保存名字默认就好,提示成功之后,剩下的就是修复的问题了。我使用的是ImpREC 1.7e,关闭OD,运行FSCapture.exe,打开ImpREC 1.7e,进程列表中选择FSCapture,界面如下图:
在“1”区域添入OEP的RVA,点击后面的“IAT AutoSearch”,如果成功,“2”区域就会被自动填充(要是不成功,就需要使用OD自己分析,然后自己添充,下面我会说这一点。),这步完成后,点击GetImports,所有找到的函数会被列在“1”区域上面的上面的列表中,但是有的有效有的无效,点击右边的Show Invalid,我们只关注无效的入口,竟然有3个无效入口,如图:
我判断这里是误判,为了复习,我就手动在OD中查看确认下。再次打开OD,来到OEP, 在OD的数据窗口中CTRL+G,输入无效入口RVA+模块地址(04000000),为了方便查看,右键设置显示方式为Integer->Address,效果如图:
这里就可以看到此入口对应的函数名,据此就可以修复无效的入口,可以看出的确是误报。确认之后就可以点击Fix Dump了。好了,运行作品试试可否顺利运行吧(我这里已经成功运行)。
最后说下,手动查找IAT:
打开OD,载入FSCapture.exe,来到OEP,滚动代码,查找类似
Address Hex dump Command Comments
007191FD |. E8 6EE0CEFF CALL <JMP.GetLastError> ; [KERNEL32.GetLastError
这种形式的CALL,follow 它,就可以来到IAT中,然后前后翻得到IAT的始RVA和末RVA,就可以计算出IAT 大小,这样就得到了整个IAT.
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课