一个PESpin保护程序脱壳调试报告

【文章标题】: 一个PESpin保护程序脱壳调试报告

【文章作者】: eJamse

【下载地址】: 见附件(目标extdfx169.exe、dumped_extdfx169.exe、PESpin 1.x - Code Fixer.txt)

【加壳方式】: PESpin

【使用工具】: OD PEID LordPE ImportRec UIF ResEdit-x86 破解计算器

【操作平台】: 虚拟机WinXP sp3

【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!


详细过程

PEID查壳,显示为“PESpin 0.3x - 1.xx -> cyberbob”。双击文件运行,打开任务管理器发现只有一个进程。用OD载入文件,开始我们的脱壳之旅。


一、Рикардо Нарваха(RicardoNarvaja李嘉图纳尔瓦哈)分析法(由点突破,恢复IAT及IAT2):

1、ESP定律结合M镜像401000处F2下断找到OEP=004032D6(以后可以HE 004032D6直接运行到OEP):

或者OD载入目标extdfx169.exe,忽略所有异常,单步F7两次,ESP变红,下硬件断点,F9两次,停在

00416ADA  F7D2  not edx ; ntdll.KiFastSystemCallRet

查看前面一句,是:

00416AD9 61 popad


2、此时(壳已经解码完成)找到两个关键点以便下硬件执行断点HE(下面会介绍由来):

二进制搜索89 07 EB 02 02 F5 F9找到关键点

00416010  8907 mov dword ptr ds:[edi],eax

00416012 EB 02 jmp short extdfx16.00416016

00416014  02F5 add dh,ch

00416016 F9                           stc

也可以直接二进制搜索897424 1C找到另一关键点:

00415BC4 897424 1C                    mov dword ptr ss:[esp+1C],esi


3、找到IAT及IAT2:

按“C”钮回到00416ADA,继续单步F7到OEP=004032D6(没有偷代码),查找模块间的直接调用,随便找一项:

00401019 call extdfx16.00407B3E 目标=COMCTL32.DefSubclassProc

跟随得出ds:[00408000]=77192041 (COMCTL32.DefSubclassProc)

定位输入表范围

IAT=00408000-00408188...(数据窗口00408000跟随为77192041)

查找模块间的间接调用,随便找一项。

00401028 call dword ptr ds:[4195F3] 目标=ds:[004195F3]=0095094F

逐步跟随得出调用的是USER32.77D2993A

重定位IAT2范围

IAT2=0041945D-00419852...(数据窗口004195F3跟随为0095094F,揪住不放,由点突破,进行下一步)


4、修复IAT及IAT2:

删除所有断点,再HW 004195F3并重启OD,多次F9运行程序。

当数据窗口004195F3为0095094F时,排除混淆找到。

00416010  8907 mov dword ptr ds:[edi],eax ;由0041600A处jmp来

00416012 /EB 02 jmp short extdfx16.00416016

HE 00416010再多次F9运行,观察数据窗口IAT2、寄存器窗口的变化重启OD并F9运行(第一次F9后数据窗口跟随004195F3),数据窗口定位004195F3的前一行004195E3,继续多次F9,直到004195EE(004195F3的前一项)还没被写入00950935时停下,Ctrl+T设置自动跟踪的条件:

(当然也可以删除所有断点,HW 004195EE后重启OD并F9运行到断下,数据窗口跟随004195EE直到ds:[004195EE]=00950935)

EAX==0095094F||EBX==0095094F||ECX==0095094F||EDX==0095094F||ESI==0095094F||EDI==0095094F

删除所有断点Ctrl+F11跟踪进入,直到停在:

00415BC4 897424 1C                    mov dword ptr ss:[esp+1C],esi

改变跟踪条件,观察77D2993A首次出现的地方。

EAX==77D2993A||EBX==77D2993A||ECX==77D2993A||EDX==77D2993A||ESI==77D2993A||EDI==77D2993A

继续跟踪,停在:

00415CAB 8BC6  mov eax,esi ; USER32.77D2993A

删除所有断点,重新HE 00416010及HE 00415BC4,重启OD并F9运行,停在:

00415BC4 897424 1C                    mov dword ptr ss:[esp+1C],esi

改成

00415BC4 894424 1C                    mov dword ptr ss:[esp+1C],eax

继续F9,停在:

00416010  8907 mov dword ptr ds:[edi],eax

改成

0041600A 90 nop

0041600B 90 nop

0041600C 90 nop

0041600D 90 nop

0041600E 8902 mov dword ptr ds:[edx],eax

00416010  8907 mov dword ptr ds:[edi],eax

删除所有断点,打开M内存镜像,在401000处F2下断,F9来到OEP=004032D6处,数据窗口观察IAT及IAT2已恢复(上面这步打酱油的,主要学习他的分析方法,得个感性认识)。

二、ximo(徐超)脱壳方法(API处理):

重启OD后HE 00416010并F9运行到断下来,注意堆栈:

$-3C     > 7C865C8B  kernel32.7C865C8B

$-38 > 0000000C

00416010  8907 mov dword ptr ds:[edi],eax

00416012 EB 02 jmp short extdfx16.00416016

00416014  02F5 add dh,ch

00416016 F9                       stc

patch如下代码:

00416010 - E9 EB9F5400              jmp 00960000

00416015  90 nop

00416016 F9                       stc

00960000  8B4424 C4                mov eax,dword ptr ss:[esp-3C]

00960004  2B4424 C8                sub eax,dword ptr ss:[esp-38]

00960008  8907 mov dword ptr ds:[edi],eax

0096000A   - E9 0760ABFF              jmp extdfx16.00416016

8B 44 24 C4 2B 44 24 C8 89 07 E9 07 60 AB FF

删除所有断点,打开M镜像00401000处F2下断,F9运行,到达OEP=004032D6。

右键查找所有模块间调用,发现所有API都回来了,除了这里:

00401950 FF15 56984100 call dword ptr ds:[419856]

ds:[00419856]=00930000这里壳解码子程序到临时空间00930000

跟随找到子程序,以备后用(脱壳后怕有功能缺失,原程序点击图片会访问网站,我这里已经失效变成关闭功能了):

00930003  9C                           pushfd

00930007  60 pushad

00930008  8B4424 24 mov eax,dword ptr ss:[esp+24]

0093000C 8B08                         mov ecx,dword ptr ds:[eax]

0093000E 8D78 04 lea edi,dword ptr ds:[eax+4]

00930011  897C24 24 mov dword ptr ss:[esp+24],edi

00930015  81E9 CDEF041F                sub ecx,1F04EFCD

0093001B     FC                           cld

00930028  8A07                         mov al,byte ptr ds:[edi]

00930030 C0C0 95 rol al,95

00930033  90 nop

00930034 F8                           clc

00930035 F9                           stc

00930036 F9                           stc

00930037  04 93 add al,93

00930039  0AC0 or al,al

0093003B 90 nop

0093003C 0AC0 or al,al

0093003E     F8                           clc

0093003F     FEC8                         dec al

00930041  2C 51 sub al,51

00930046 FEC8                         dec al

00930048  34 21 xor al,21

00930050 FEC8                         dec al

00930052 AA                           stos byte ptr es:[edi]

00930053  49 dec ecx

00930054 ^ 75 D2                        jnz short 00930028(留心)

0093005F 61 popad

00930060  9D                           popfd

00930061 C3                           retn

9C608B4424 248B088D78 04897C24 2481E9 CDEF041FFC8A07C0C0 9590F8F9F904 930AC0 900AC0F8 FEC82C 51FEC8 34 21 FEC8 AA 4975 D2619DC3

找到空白处修复,变成

00401950 E8 18620000 call extdfx16.00407B6D

00401955  90 nop

00407B6D 9C                           pushfd

00407B6E 60 pushad

00407B6F 8B4424 24 mov eax,dword ptr ss:[esp+24]

00407B73 8B08                         mov ecx,dword ptr ds:[eax]

00407B75 8D78 04 lea edi,dword ptr ds:[eax+4]

00407B78 897C24 24 mov dword ptr ss:[esp+24],edi

00407B7C 81E9 CDEF041F                sub ecx,1F04EFCD

00407B82     FC                           cld

00407B83 8A07                         mov al,byte ptr ds:[edi]

00407B85     C0C0 95 rol al,95

00407B88 90 nop

00407B89     F8                           clc

00407B8A     F9                           stc

00407B8B     F9                           stc

00407B8C 04 93 add al,93

00407B8E 0AC0 or al,al

00407B90 90 nop

00407B91 0AC0 or al,al

00407B93     F8                           clc

00407B94     FEC8                         dec al

00407B96 2C 51 sub al,51

00407B98     FEC8                         dec al

00407B9A 34 21 xor al,21

00407B9C     FEC8                         dec al

00407B9E     AA                           stos byte ptr es:[edi]

00407B9F 49 dec ecx

00407BA0   ^ 75 E1 (指向8A07一句)       jnz short dumped_e.00407B83

00407BA2 61 popad

00407BA3 9D                           popfd

00407BA4     C3                           retn

9C 60 8B 44 24 24 8B 08 8D 78 04 89 7C 24 24 81 E9 CD EF 04 1F FC 8A 07 C0 C0 95 90 F8 F9 F9 04

93 0A C0 90 0A C0 F8 FE C8 2C 51 FE C8 34 21 FE C8 AA 49 75 E1 61 9D C3


三、处理Code Redirection

(没有偷代码,有定向到PE头):多次运行PESpin 1.x - Code Fixer.txt修复脚本,不能再修复为止。

第一种重定向(CALL-JMP):特征码#E8??????FF#

00401DA8  E8 8AE4FFFF call extdfx16.00400237

第二种重定向(JMP-PUSH):特征码#E9??????FF#

00401D2A  - E9 ADE4FFFF jmp extdfx16.004001DC

第三种重定向(JMP- CMP):特征码#E9??????FF9090#

00401D35  - E9 ADE4FFFF jmp extdfx16.004001E7

00401D3A 90 nop

00401D3B 90 nop


四、UIF修复指针:

API大多被定向到壳地址,我们想把它放在0040A000段(看M镜像)

此处省去口口口口......10000多字,请看ximo老师教程


五、Dump:

LordPE(修正大小)来Dump为dumped.exe,填入OEP:32D6,ImportREC自动方式获取API,转存为dumped_.exe后发现不能运行。


六、BUG修复:

注:以下老OD是载入目标extdfx169.exe,并且HE 004032D6直接运行到OEP。

先前载入目标extdfx169.exe走到OEP的OD不要关(也不要运行,需要时只是跟随查找),以便对比。

1、另开OD载入dumped_.exe,发现堆栈不对(不知道是不是防Dump的地方没有处理好?)

老OD栈顶:0012FFC0 00416B0B extdfx16.00416B0B(返回值)

跟随发现实际返回到这里00401A6C 6A 60 push 60

新OD栈顶:0012FFC4 7C817077 返回到 kernel32.7C817077 

所以只需找空地PUSH 00401A6C再返回到旧OEP就好了,例如:

00407B63 68 6C1A4000 push dumped_.00401A6C

00407B68 ^ E9 69B7FFFF jmp dumped_.<模块入口点>

保存修改到文件dumped_1.exe,用LordPE改变入口OEP=00007B63并验证重建一下 ,可以运行了 。


七、Win7平台兼容问题:

Win7下运行dumped_1.exe发生BEX故障。

原因是不同系统下,同名API的地址不同。手动更改下,可以运行,但功能可能受影响(修改不全的话)。

例如:Win7下OD载入dumped_1.exe找到问题点换成Win7认可的API地址

004019F8 3B0D 50A04000            cmp ecx,dword ptr ds:[40A050]

ds:[0040A050]=7C865525

ecx=757C178E (kernel32.Module32Next)

XP下OD载入dumped_1.exe运行到该处,对比后,数据窗口跟随改成ds:[0040A050]=757C178E。

保存修改到文件dumped_extdfx169_win7.exe,此时Win7下可以运行了。

兼容问题后来发现有个简便方法:

dumped_extdfx169_XP.exe里改为下面几句就OK了!

004019F8 890D 50A04000                mov dword ptr ds:[40A050],ecx

004019FE 90 nop

004019FF 90 nop

偷懒笨办法(XP系统下API地址拷贝出来翻译成Win7系统下API地址再刷回去):


XP系统下

0040A000 7C9300A4 ntdll.RtlAllocateHeap

0040A004 7C92FF0D ntdll.RtlFreeHeap

0040A008 7C92FE01 ntdll.RtlGetLastWin32Error

0040A00C 7C92FE10 ntdll.RtlSetLastWin32Error

0040A010 7C93135A ntdll.RtlDeleteCriticalSection

0040A014 7C9210E0 ntdll.RtlLeaveCriticalSection

0040A018 7C921000 ntdll.RtlEnterCriticalSection

0040A01C 7C939B80 ntdll.RtlReAllocateHeap

0040A020 7C9304BD ntdll.RtlSizeHeap

0040A024 7C94ABA5 ntdll.RtlUnwind

0040A028 7C809BE7 kernel32.CloseHandle

0040A02C 7C8309E9 kernel32.OpenProcess

0040A030 7C8021D0 kernel32.ReadProcessMemory

0040A034 7C809EA1 kernel32.IsBadReadPtr

0040A038 7C802213 kernel32.WriteProcessMemory

0040A03C 7C809B12 kernel32.VirtualAllocEx

0040A040 7C809BA2 kernel32.VirtualFreeEx

0040A044 7C8650C8 kernel32.Process32Next

0040A048 7C864F55 kernel32.Process32First

0040A04C 7C865C7F kernel32.CreateToolhelp32Snapshot

0040A050 7C865525 kernel32.Module32Next

0040A054 7C8653A0 kernel32.Module32First

0040A058 7C801EF2 kernel32.GetStartupInfoA

0040A05C 7C80AC61 kernel32.GetProcessHeap

0040A060 7C812B7E kernel32.GetVersionExA

0040A064 7C812FBD kernel32.GetCommandLineA

0040A068 7C813133 kernel32.IsDebuggerPresent

0040A06C 7C84495D kernel32.SetUnhandledExceptionFilter

0040A070 7C863FCA kernel32.UnhandledExceptionFilter

0040A074 7C80DE95 kernel32.GetCurrentProcess

0040A078 7C801E1A kernel32.TerminateProcess

0040A07C 7C80B741 kernel32.GetModuleHandleA

0040A080 7C80AE40 kernel32.GetProcAddress

0040A084 7C81CB12 kernel32.ExitProcess

0040A088 7C80B56F kernel32.GetModuleFileNameA

0040A08C 7C812FD9 kernel32.GetStdHandle

0040A090 7C810E27 kernel32.WriteFile

0040A094 7C812FA8 kernel32.GetEnvironmentStringsW

0040A098 7C80A174 kernel32.WideCharToMultiByte

0040A09C 7C814B87 kernel32.FreeEnvironmentStringsW

0040A0A0 7C81CC93 kernel32.GetEnvironmentStringsA

0040A0A4 7C81D6EF kernel32.FreeEnvironmentStringsA

0040A0A8 7C810EF1 kernel32.GetFileType

0040A0AC 7C80CD37 kernel32.SetHandleCount

0040A0B0 7C8097E0 kernel32.TlsGetValue

0040A0B4 7C812E3F kernel32.TlsAlloc

0040A0B8 7C809C65 kernel32.TlsSetValue

0040A0BC 7C813777 kernel32.TlsFree

0040A0C0 7C809806 kernel32.InterlockedIncrement

0040A0C4 7C8097D0 kernel32.GetCurrentThreadId

0040A0C8 7C80981A kernel32.InterlockedDecrement

0040A0CC 7C812C56 kernel32.HeapCreate

0040A0D0 7C810F98 kernel32.HeapDestroy

0040A0D4 7C8017E9 kernel32.GetSystemTimeAsFileTime

0040A0D8 7C8099C0 kernel32.GetCurrentProcessId

0040A0DC 7C80934A kernel32.GetTickCount

0040A0E0 7C80A4C7 kernel32.QueryPerformanceCounter

0040A0E4 7C809F91 kernel32.InitializeCriticalSection

0040A0E8 7C801D7B kernel32.LoadLibraryA

0040A0EC 7C812F16 kernel32.GetCPInfo

0040A0F0 7C812847 kernel32.GetOEMCP

0040A0F4 7C8099B5 kernel32.GetACP

0040A0F8 7C802446 kernel32.Sleep

0040A0FC 7C809B84 kernel32.VirtualFree

0040A100 7C809AF1 kernel32.VirtualAlloc

0040A104 7C80CD48 kernel32.LCMapStringW

0040A108 7C809C98 kernel32.MultiByteToWideChar

0040A10C 7C838E18 kernel32.LCMapStringA

0040A110 7C80A530 kernel32.GetStringTypeW

0040A114 7C838A3C kernel32.GetStringTypeA

0040A118 7C80D302 kernel32.GetLocaleInfoA

0040A11C 00000000

0040A120 77D29930 USER32.SetCursor

0040A124 77D507EA USER32.MessageBoxA

0040A128 77D2A78F USER32.GetAsyncKeyState

0040A12C 77D2436E USER32.GetDlgItem

0040A130 77D2F56B USER32.SetWindowTextA

0040A134 77D2F3C2 USER32.SendMessageA

0040A138 77D18C2E USER32.SetTimer

0040A13C 77D18C42 USER32.KillTimer

0040A140 77D24A4E USER32.EndDialog

0040A144 77D27C08 USER32.LoadImageA

0040A148 77D3B144 USER32.DialogBoxParamA

0040A14C 77D2D33E USER32.LoadCursorA

0040A150 00000000

0040A154 77192041COMCTL32.DefSubclassProc

0040A158 771921FA COMCTL32.SetWindowSubclass


Win7系统下:

0040A000 773829BE ntdll.RtlAllocateHeap

0040A004 77382852ntdll.RtlFreeHeap

0040A008 7739998D ntdll.RtlGetLastWin32Error

0040A00C 77382CE3 ntdll.RtlSetLastWin32Error

0040A010 77389911ntdll.RtlDeleteCriticalSection

0040A014 773772A0 ntdll.RtlLeaveCriticalSection

0040A018 773772E0 ntdll.RtlEnterCriticalSection

0040A01C 7739FB76 ntdll.RtlReAllocateHeap

0040A020 77389A38 ntdll.RtlSizeHeap

0040A024 7734FA80 ntdll.RtlUnwind

0040A028 7577EA18 kernel32.CloseHandle

0040A02C 757756A7 kernel32.OpenProcess

0040A030 7576C9A3 kernel32.ReadProcessMemory

0040A034 7576BE6B kernel32.IsBadReadPtr

0040A038 7579979F kernel32.WriteProcessMemory

0040A03C 7576C98B kernel32.VirtualAllocEx

0040A040 7576C9B3 kernel32.VirtualFreeEx

0040A044 757964B5 kernel32.Process32Next

0040A048 757963ED kernel32.Process32First

0040A04C 7576FEEA kernel32.CreateToolhelp32Snapshot

0040A050 757C178E kernel32.Module32Next

0040A054 757C16A5 kernel32.Module32First

0040A058 75731E10 kernel32.GetStartupInfoA

0040A05C 7577FE8D kernel32.GetProcessHeap

0040A060 7577DF30 kernel32.GetVersionExA

0040A064 7578908F kernel32.GetCommandLineA

0040A068 75777FDA kernel32.IsDebuggerPresent

0040A06C 7577F6AB kernel32.SetUnhandledExceptionFilter

0040A070 75790851kernel32.UnhandledExceptionFilter

0040A074 7577D950 kernel32.GetCurrentProcess

0040A078 75772DC5 kernel32.TerminateProcess

0040A07C 7577DAA3 kernel32.GetModuleHandleA

0040A080 7577CE44 kernel32.GetProcAddress

0040A084 7578BDE2 kernel32.ExitProcess

0040A088 7577D90A kernel32.GetModuleFileNameA

0040A08C 75789077kernel32.GetStdHandle

0040A090 757855A6 kernel32.WriteFile

0040A094 75786D7C kernel32.GetEnvironmentStringsW

0040A098 7577F0AA kernel32.WideCharToMultiByte

0040A09C 75786D64 kernel32.FreeEnvironmentStringsW

0040A0A0 7578CA91 kernel32.GetEnvironmentStringsA

0040A0A4 7578CA72 kernel32.FreeEnvironmentStringsA

0040A0A8 75786C6C kernel32.GetFileType

0040A0AC 757890A1 kernel32.SetHandleCount

0040A0B0 7577F910 kernel32.TlsGetValue

0040A0B4 7577D9B4 kernel32.TlsAlloc

0040A0B8 7577F933 kernel32.TlsSetValue

0040A0BC 75785411kernel32.TlsFree

0040A0C0 7577C560 kernel32.InterlockedIncrement

0040A0C4 7577C5C0 kernel32.GetCurrentThreadId

0040A0C8 7577C590 kernel32.InterlockedDecrement

0040A0CC 7577F124 kernel32.HeapCreate

0040A0D0 75772D95 kernel32.HeapDestroy

0040A0D4 7577D9C6 kernel32.GetSystemTimeAsFileTime

0040A0D8 7577D965 kernel32.GetCurrentProcessId

0040A0DC 7577C440 kernel32.GetTickCount

0040A0E0 7577C5D2 kernel32.QueryPerformanceCounter

0040A0E4 7C809F91 kernel32.InitializeCriticalSection;找不到

0040A0E8 7577DE15 kernel32.LoadLibraryA

0040A0EC 7578905F kernel32.GetCPInfo

0040A0F0 757745CA kernel32.GetOEMCP

0040A0F4 7577DABB kernel32.GetACP

0040A0F8 7577C426 kernel32.Sleep

0040A0FC 75786CCD kernel32.VirtualFree

0040A100 7577C5EA kernel32.VirtualAlloc

0040A104 75785444kernel32.LCMapStringW

0040A108 7577F0B7 kernel32.MultiByteToWideChar

0040A10C 7578FB20 kernel32.LCMapStringA

0040A110 757854E6 kernel32.GetStringTypeW

0040A114 7C838A3C kernel32.GetStringTypeA;找不到

0040A118 7576B57B kernel32.GetLocaleInfoA

0040A11C 00000000

0040A120 7586304D USER32.SetCursor

0040A124 758AEA89 USER32.MessageBoxA

0040A128 7585A226 USER32.GetAsyncKeyState

0040A12C 7588428B USER32.GetDlgItem

0040A130 75880C2B USER32.SetWindowTextA

0040A134 7585AD30 USER32.SendMessageA

0040A138 758652C7 USER32.SetTimer

0040A13C 758664CF USER32.KillTimer

0040A140 75883B73 USER32.EndDialog

0040A144 75877749USER32.LoadImageA

0040A148 7589CFB8 USER32.DialogBoxParamA

0040A14C 75858318USER32.LoadCursorA

0040A150 00000000

0040A154 7400F56C COMCTL32.DefSubclassProc

0040A158 73FF400A COMCTL32.SetWindowSubclass

二进制代码如下:

BE 29 38 77 52 28 38 77 8D 99 39 77 E3 2C 38 77 11 99 38 77 A0 72 37 77 E0 72 37 77 76 FB 39 77

38 9A 38 77 80 FA 34 77 18 EA 77 75 A7 56 77 75 A3 C9 76 75 6B BE 76 75 9F 97 79 75 8B C9 76 75

B3 C9 76 75 B5 64 79 75 ED 63 79 75 EA FE 76 75 8E 17 7C 75 A5 16 7C 75 10 1E 73 75 8D FE 77 75

30 DF 77 75 8F 90 78 75 DA 7F 77 75 AB F6 77 75 51 08 79 75 50 D9 77 75 C5 2D 77 75 A3 DA 77 75

44 CE 77 75 E2 BD 78 75 0A D9 77 75 77 90 78 75 A6 55 78 75 7C 6D 78 75 AA F0 77 75 64 6D 78 75

91 CA 78 75 72 CA 78 75 6C 6C 78 75 A1 90 78 75 10 F9 77 75 B4 D9 77 75 33 F9 77 75 11 54 78 75

60 C5 77 75 C0 C5 77 75 90 C5 77 75 24 F1 77 75 95 2D 77 75 C6 D9 77 75 65 D9 77 75 40 C4 77 75

D2 C5 77 75 91 9F 80 7C 15 DE 77 75 5F 90 78 75 CA 45 77 75 BB DA 77 75 26 C4 77 75 CD 6C 78 75

EA C5 77 75 44 54 78 75 B7 F0 77 75 20 FB 78 75 E6 54 78 75 3C 8A 83 7C 7B B5 76 75 00 00 00 00

4D 30 86 75 89 EA 8A 75 26 A2 85 75 8B 42 88 75 2B 0C 88 75 30 AD 85 75 C7 52 86 75 CF 64 86 75

73 3B 88 75 49 77 87 75 B8 CF 89 75 18 83 85 75 00 00 00 00 6C F5 00 74 0A 40 FF 73


八、脱壳后的程序标题栏和关于栏有乱码,带壳运行目标extdfx169.exe,对比后更改如下:

1、about(这一步在XP下处理的)

00401931     8B15 0CE04100            mov edx,dword ptr ds:[<&kernel32.SetLas>; kernel32.SetLastError

改成:

00401931     BA B0814000              mov edx,dumped_e.004081B0

00401936     90                       nop

顺便用ResEdit-x86汉化下主界面,增加最小化按钮,在about还更改了一句:请使用数字小键盘!


2、标题栏:Win7下标题为'閩?悙悙惛榲u脨悙悙?U嬱Q婨?..'(问题越明显越好找,XP下反而不好找)

Win7下OD载入dumped_extdfx169_win7.exe后,F8运行N步,我这里堆栈栏有:

0012F7A4 002B09F0  |hOwner = 002B09F0 ('閩?悙悙惛榲u脨悙悙?U嬱Q婨?..',class='#32770')

用破解计算器找到ASCII码:

悙悙惛榲=90 90 90 90 90 B8 98 76

u脨悙悙=75 C3 90 90 90 90 90

U嬱Q婨=FF 55 8B EC 51 8B

在M镜像二进制查找90 90 90 90 90 B8 98 76,来到:

7577CF8590 90 90 90 90 90 90 90 90 90 90 E9 7D F6 FF FF  悙悙悙悙悙閩?

7577CF9590 90 90 90 90 B8 98 76 7F 75 C3 90 90 90 90 90 悙悙惛榲u脨悙悙

7577CFA58B FF 55 8B EC 51 8B 45 10 8B 4D 08 53 8B 5D 14 ?U嬱Q婨婱S媇

看来标题栏引用的地址是:7577CF90(这可是API地址啊!) 高低位转换成90CF7775。

在M镜像二进制查找90CF7775,得到:

0041E008 >90 CF 77 75

反汇编窗口转到0041E008,却是:

0041E008 <>90 nop

0041E009 CF                       iretd

0041E00A 77 75 ja short dumped_e.0041E081

不管他,仍然HR 0041E008,重启OD连续F9,停在:

004018CE     50                       push eax ; kernel32.GetLastError

eax=7577CF90 (kernel32.GetLastError)

OD带壳运行目标extdfx169.exe,此处却是:

004018CE 50 push eax ; extdfx16.00408214

eax=00408214 (extdfx16.00408214), ASCII "Trainer +6"

直接修改dumped_extdfx169_win7.exe相应堆栈值为00408214,运行后正常了!

修改如下:

004018C9  A1 08E04100 mov eax,dword ptr ds:[<&kernel32.GetLastError>]

改成

004018C9  B8 14824000mov eax,dumped_e.00408214 ; ASCII "Trainer +6"

后来才知道也可以这样查找:

1、在反汇编窗口查找所有常量=0041E008,找到这些:

参考位于 dumped_e:到常量41E008

地址       反汇编                                           注释

004018C9   mov eax,dword ptr ds:[<&kernel32.GetLastError>]  [0041E008]=7577CF90

00402764  call dword ptr ds:[<&kernel32.GetLastError>]     kernel32.GetLastError

00402CE6 call dword ptr ds:[<&kernel32.GetLastError>]     kernel32.GetLastError

00404824  call dword ptr ds:[<&kernel32.GetLastError>]     kernel32.GetLastError

00405E46 call dword ptr ds:[<&kernel32.GetLastError>]     kernel32.GetLastError

00406228  call dword ptr ds:[<&kernel32.GetLastError>]     kernel32.GetLastError

0040678C call dword ptr ds:[<&kernel32.GetLastError>]     kernel32.GetLastError

00406819  call dword ptr ds:[<&kernel32.GetLastError>]     kernel32.GetLastError

00407B63   push dumped_e.00401A6C                           (初始 CPU 选择)


2、第一句就是所求正解


九、思考:

脱壳后的程序为什么访问0041E008的数据?ds:[0041E008]的数据又如何由00408214变成了7577CF90?

感觉程序好像错位了,是反Dump造成的吗?那功能还有保障吗?


原文作者:ejamse

原文链接:https://bbs.pediy.com/thread-249384.htm

转载请注明:转自看雪学院


更多阅读:

windows常用的反调试技术-静态反调试技术

正确生成随机数的两种姿势

2018-XNUCA-steak

Cheat Engine进阶教程:gtutorial-i386闯关记 第三关 [完结撒花]

你可能感兴趣的:(一个PESpin保护程序脱壳调试报告)