Here is a unpacker for PECompact packed dll, but there are some error occur: 1、CreateProcess use command line: loaddll.exe *.dll (just like ollydbg) 2、While CREATE_PROCESS_DEBUG_EVENT,log the DBEvent.u.CreateProcessInfo.hProcess and DBEvent.u.CreateProcessInfo.hThread 3、While LOAD_DLL_DEBUG_EVENT, when load *.dll, SuspendThread DBEvent.u.CreateProcessInfo.hThread, than set breakpoint in OEP,and ResumeThread DBEvent.u.CreateProcessInfo.hThread, while GetThreadContext, Context.regEip always stop in ntdll.KiFastSystemCallRet, can not get dll's regEip: Код (Text): ProcessDll proc LOCAL Buffer [64]:byte LOCAL BP1_data,BP2_data,BP3_data,BP4_data:DWORD LOCAL BP1,BP2,BP3,BP4:DWORD LOCAL hProcess:dword LOCAL tempaddr:dword LOCAL dlls_imported,PatchAddr:dword LOCAL szContext[1024]:byte LOCAL TEB,LDR:dword mov flag,0 invoke GetTempPath, sizeof TempPath, addr TempPath invoke wsprintf,addr OutBuff,addr Format,addr loaddllPath,addr FilePath ;loaddll.exe 2.dll invoke GetStartupInfo,addr startinfo invoke CreateProcess,NULL,addr OutBuff,NULL,NULL,FALSE,DEBUG_PROCESS+DEBUG_ONLY_THIS_PROCESS ,NULL,addr TempPath,addr startinfo,addr ProcessInfo .while TRUE invoke WaitForDebugEvent,addr DBEvent,INFINITE mov dwDebugOperation,DBG_CONTINUE .if DBEvent.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT invoke OutputInfo,CTEXT("Exit Debug"),0 .break .elseif DBEvent.dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT mov edx,DBEvent.u.CreateProcessInfo.hProcess mov myProcess,edx mov ecx,DBEvent.u.CreateProcessInfo.hThread mov myThread,ecx .elseif DBEvent.dwDebugEventCode == LOAD_DLL_DEBUG_EVENT mov Context.ContextFlags,CONTEXT_FULL invoke GetThreadContext,myThread,addr Context invoke wsprintf,addr OutBuff,CTEXT("regEip %.08X",13,10,0),Context.regEip invoke OutputInfo,addr OutBuff,0 invoke GetThreadSelectorEntry,myThread,Context.regFs,addr ldte mov ah,[ldte.HighWord1.Bytes.BaseHi] shl eax,16 mov ax,[ldte.BaseLow] assume fs:nothing mov eax,fs:[18h] mov eax,[eax+30h] mov eax,DBEvent.u.LoadDll.lpBaseOfDll mov dwModBase,eax .if dwModBase < 60000000h invoke ReadProcessMemory,myProcess,DBEvent.u.LoadDll.lpImageName,addr OutBuff,4,NULL mov eax,dword ptr OutBuff invoke ReadProcessMemory,myProcess,eax,addr pDllName,256,NULL invoke Unicode2Ansi,addr pDllName,addr outinf invoke lstrcmp,addr outinf,addr FilePath .if eax==0 inc flag invoke wsprintf,addr OutBuff,CTEXT("LoadDll sucess: handle:%08Xh,base:%08Xh,name:%s",13,10,0),DBEvent.u.LoadDll.hFile,DBEvent.u.LoadDll.lpBaseOfDll,addr outinf invoke OutputInfo,addr OutBuff,0 mov esi,DBEvent.u.LoadDll.lpBaseOfDll mov DllBase,esi mov eax,DBEvent.u.LoadDll.hFile mov hDll,eax .elseif flag==1 mov edi,DllBase add edi,EntryPiont add edi,1 lea esi,Buffer invoke ReadProcessMemory,myProcess,edi,esi,4,0 mov edi,dword ptr [esi] invoke wsprintf,addr OutBuff,CTEXT("%s: %.08X",13,10,0),CTEXT("Got the address of mov eax,xxxxxxxx "),edi invoke OutputInfo,addr OutBuff,0 invoke Searchcode,myProcess,edi,0ffd7h .if eax==0 invoke MessageBox,0,CTEXT("Searchcode Error"),0,MB_OK jmp @@exit .endif mov BP1,eax invoke ReadProcessMemory,myProcess,BP1,addr BP1_data,2,0 invoke WriteProcessMemory,myProcess,BP1,CTEXT(0EBh,0FEh),2,0 invoke wsprintf,addr OutBuff,CTEXT("%s: %.08X",13,10,0),CTEXT("Set Breakpoint in 'CALL EDI' "),BP1 invoke OutputInfo,addr OutBuff,0 invoke Searchcode,myProcess,BP1,0FFe0h mov BP2,eax invoke wsprintf,addr OutBuff,CTEXT("%s: %.08X",13,10,0),CTEXT("Set Breakpoint in 'JMP EAX' "),BP2 invoke OutputInfo,addr OutBuff,0 invoke ReadProcessMemory,myProcess,BP2,addr BP2_data,2,0 invoke WriteProcessMemory,myProcess,BP2,CTEXT(0CCh,00h),2,0 _10MB equ 1024*1024*10 invoke VirtualAlloc,0,_10MB,MEM_COMMIT,PAGE_READWRITE mov pNewImports,eax invoke OutputInfo,CTEXT("Start Unpacking...",13,10,0),0 invoke ResumeThread,myThread invoke Sleep,100 mov esi,pNewImports assume esi:ptr IMAGE_IMPORT_DESCRIPTOR mov dlls_imported,0 mov borland_flag,FALSE mov redirection_flag,FALSE @loop: invoke SuspendThread,myThread mov Context.ContextFlags,CONTEXT_FULL invoke GetThreadContext,myThread,addr Context ;///////////////////////////////////////////////////////////// ;Error here, Context.regEip=ntdll.KiFastSystemCallRet always mov eax,Context.regEip ;///////////////////////////////////////////////////////////// .if eax==BP1 invoke WriteProcessMemory,myProcess,BP1,addr BP1_data,2,0 mov eax,Context.regEdi mov tempaddr,eax invoke Searchcode,myProcess,eax,5751h add eax,3 mov ebx,eax mov BP3,ebx invoke ReadProcessMemory,myProcess,BP3,addr BP3_data,2,0 invoke WriteProcessMemory,myProcess,ebx,CTEXT(0EBh,0FEh),2,0 add ebx,6 mov BP4,ebx invoke ReadProcessMemory,myProcess,BP4,addr BP4_data,2,0 invoke Searchcode,myProcess,tempaddr,4040h invoke Searchcode,myProcess,tempaddr,8902h add eax,1 mov PatchAddr,eax invoke WriteProcessMemory,myProcess,eax,CTEXT(16h),1,0 .elseif eax==BP3 invoke WriteProcessMemory,myProcess,BP3,addr BP3_data,2,0 invoke WriteProcessMemory,myProcess,BP4,CTEXT(0EBh,0FEh),2,0 mov eax,Context.regEcx sub eax,DllBase mov [esi].Name1,eax mov eax, Context.regEdi .if borland_flag!=TRUE pushad invoke ReadProcessMemory,myProcess,Context.regEdi,addr Buffer,4,0 .if Buffer!=0 mov ebx,PatchAddr sub ebx,3 invoke WriteProcessMemory,myProcess,ebx,CTEXT(90h,90h,90h,90h),4,0 mov borland_flag,TRUE invoke OutputInfo,CTEXT("Borland stuff detected - inject code",13,10,0),0 .endif no_borland: popad .endif sub eax,ImageBase mov [esi].FirstThunk,eax add esi,sizeof IMAGE_IMPORT_DESCRIPTOR inc dlls_imported .elseif eax==BP4 invoke WriteProcessMemory,myProcess,BP4,addr BP4_data,2,0 invoke WriteProcessMemory,myProcess,BP3,CTEXT(0EBh,0FEh),2,0 .elseif eax==BP2 invoke WriteProcessMemory,myProcess,BP2,addr BP2_data,2,0 invoke wsprintf,addr OutBuff,CTEXT("Set BreakPoint in %.08X ",13,10,0),BP2 invoke OutputInfo,addr OutBuff,0 mov eax,Context.regEax invoke wsprintf,addr OutBuff,CTEXT("%s: %.08X",13,10,0),CTEXT(13,10,"Find OEP"),eax invoke OutputInfo,addr OutBuff,0 invoke MessageBox,0,addr OutBuff,CTEXT("Got OEP"),MB_OK jmp @f .endif invoke ResumeThread,myThread invoke Sleep,8 jmp @loop @@: call FixIAT call NewPEinfo .endif @continue: .endif .elseif DBEvent.dwDebugEventCode == EXCEPTION_DEBUG_EVENT .endif invoke ContinueDebugEvent,DBEvent.dwProcessId,DBEvent.dwThreadId,dwDebugOperation .endw @@exit: invoke CloseHandle,myProcess invoke CloseHandle,ProcessInfo.hThread ret ProcessDll endp
I think I have found the solution. Код (Text): ProcessDll proc LOCAL Buffer [64]:byte LOCAL EP,EP_data:dword LOCAL hProcess:dword LOCAL tempaddr:dword LOCAL dlls_imported,PatchAddr:dword LOCAL szContext[1024]:byte LOCAL TEB,LDR:dword invoke GetTempPath, sizeof TempPath, addr TempPath invoke wsprintf,addr OutBuff,addr Format,addr loaddllPath,addr FilePath invoke GetStartupInfo,addr startinfo invoke CreateProcess,NULL,addr OutBuff,NULL,NULL,FALSE,DEBUG_PROCESS+DEBUG_ONLY_THIS_PROCESS ,NULL,addr TempPath,addr startinfo,addr ProcessInfo .while TRUE invoke WaitForDebugEvent,addr DBEvent,INFINITE .if DBEvent.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT invoke OutputInfo,CTEXT("Exit Debug"),0 .break .elseif DBEvent.dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT mov edx,DBEvent.u.CreateProcessInfo.hProcess mov myProcess,edx mov ecx,DBEvent.u.CreateProcessInfo.hThread mov myThread,ecx .elseif DBEvent.dwDebugEventCode == LOAD_DLL_DEBUG_EVENT mov eax,DBEvent.u.LoadDll.lpBaseOfDll mov dwModBase,eax .if dwModBase < 80000000h invoke ReadProcessMemory,myProcess,DBEvent.u.LoadDll.lpImageName,addr OutBuff,4,NULL mov eax,dword ptr OutBuff invoke ReadProcessMemory,myProcess,eax,addr pDllName,256,NULL invoke Unicode2Ansi,addr pDllName,addr outinf invoke lstrcmp,addr outinf,addr FilePath .if eax==0 invoke wsprintf,addr OutBuff,CTEXT("LoadDll succes: handle:%08Xh,base:%08Xh,name:%s",13,10,0),DBEvent.u.LoadDll.hFile,DBEvent.u.LoadDll.lpBaseOfDll,addr outinf invoke OutputInfo,addr OutBuff,0 mov esi,DBEvent.u.LoadDll.lpBaseOfDll mov DllBase,esi add esi,EntryPiont mov firstbp,esi mov eax,DBEvent.u.LoadDll.hFile mov hDll,eax .endif .endif .elseif DBEvent.dwDebugEventCode == EXCEPTION_DEBUG_EVENT .if DBEvent.u.Exception.pExceptionRecord.ExceptionCode==EXCEPTION_BREAKPOINT mov Context.ContextFlags, CONTEXT_FULL invoke GetThreadContext, ProcessInfo.hThread, addr Context mov eax,Context.regEip mov ecx,firstbp inc ecx .if eax == ecx dec Context.regEip invoke wsprintf,addr OutBuff,CTEXT("breakpoint at %.08X ",13,10,0),Context.regEip invoke OutputInfo,addr OutBuff,0 mov edi,Context.regEdi mov DllBase,edi mov eax,Context.regEax mov firstbp,eax mov ecx,Context.regEcx mov SizeOfImage,ecx mov edx,Context.regEdx mov oldbyte,edx invoke WriteProcessMemory,ProcessInfo.hProcess,Context.regEip,oldbyte,1,0 invoke wsprintf,addr OutBuff,CTEXT("EP: %.08X,Base: %.08X,SizeImage: %.08X ",13,10,0),firstbp,DllBase,SizeOfImage invoke OutputInfo,addr OutBuff,0 invoke MessageBox,0,addr OutBuff,CTEXT("dll info"),MB_OK invoke TerminateProcess,myProcess,0 .endif invoke ContinueDebugEvent,DBEvent.dwProcessId, DBEvent.dwThreadId, DBG_CONTINUE .continue .endif .endif invoke ContinueDebugEvent,DBEvent.dwProcessId,DBEvent.dwThreadId,DBG_CONTINUE .endw @@exit: invoke CloseHandle,myProcess invoke CloseHandle,ProcessInfo.hThread ret ProcessDll endp