1.查壳
2.find OEP
3.dump
4.fix
入口点:
mov eax,idaprohelper.44B51C push eax push dword ptr fs:[0] mov dword ptr fs:[0],esp xor eax,eax mov dword ptr ds:[eax],ecx
seh异常处理函数
设置忽略异常
异常处理函数下断,运行
SEH异常相关结构
EXCEPTION_DISPOSITION __cdecl _except_handler( _In_ struct _EXCEPTION_RECORD* _ExceptionRecord, _In_ void* _EstablisherFrame, _Inout_ struct _CONTEXT* _ContextRecord, _Inout_ void* _DispatcherContext ); typedef struct _EXCEPTION_RECORD { DWORD ExceptionCode;//+0 DWORD ExceptionFlags;//+4 struct _EXCEPTION_RECORD *ExceptionRecord;//+8 PVOID ExceptionAddress;//+c DWORD NumberParameters; ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; } EXCEPTION_RECORD; // Exception disposition return values typedef enum _EXCEPTION_DISPOSITION { ExceptionContinueExecution, ExceptionContinueSearch, ExceptionNestedException, ExceptionCollidedUnwind } EXCEPTION_DISPOSITION;
mov eax,0xF044A2A1 lea ecx,dword ptr ds:[eax+0x1000129E] mov dword ptr ds:[ecx+0x1],eax mov edx,dword ptr ss:[esp+0x4] //_ExceptionRecord mov edx,dword ptr ds:[edx+0xC] //ExceptionAddress mov byte ptr ds:[edx],0xE9 //0xe9jmp add edx,0x5 //jmp xxxx指令长度 sub ecx,edx //与jmp跳转目标地址的相对偏移(去除当前指令长度) mov dword ptr ds:[edx-0x4],ecx //构造jmp指令的目标地址 xor eax,eax // ExceptionContinueExecution ret
ExceptionAddress patch为jmp跳转
修补jmp指令:
修补jmp指令后:
异常处理函数结束,原异常地址下断,
运行:
取消断点,单步
一直单步
Jmp eax后来到OEP
脱壳后直接运行报错:
新开程序:
脱壳后
PECompact简单的压缩壳,脱壳没什么难度。