News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

dll unpack, GetThreadContext error... solution

Started by laomms, June 01, 2008, 11:50:25 PM

Previous topic - Next topic

laomms

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:


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 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




Vortex

What was the problem?

jj2007

42 plus a bit of reverse engineering, and you'll arrive at the problem, Vortex ;-)

laomms

#3
loaddll source


start:
        invoke GetModuleHandle,0
        mov hInstance,eax
        invoke GetCommandLine
        mov esi,eax
        inc esi
        cmp al, 22h
        je @next
@@:
        .if al==0
                invoke MessageBox,0,CTEXT("Missing DLL name"),0,MB_OK
                invoke ExitProcess,0
        .endif
        mov al, byte ptr [esi+1]
        inc esi
        cmp al, 22h
        jnz @b
@next:
        mov al, byte ptr [esi+1]
        inc esi
        cmp al, 20h
        jnz @load
@@:
        mov al, byte ptr [esi+1]
        inc esi
        cmp al, 20h
        je @b
@load:
        invoke LoadLibraryEx,esi,NULL,DONT_RESOLVE_DLL_REFERENCES         
        .if eax==0
                invoke MessageBox,0,CTEXT("Unable to load DLL"),0,MB_OK
                invoke ExitProcess,0
        .endif
        mov DllBase,eax
        invoke ImageNtHeader,DllBase
        mov edi,eax
        assume edi:ptr IMAGE_NT_HEADERS
        mov eax,[edi].OptionalHeader.AddressOfEntryPoint
        add eax,DllBase
        mov EP,eax
        mov ecx,[edi].OptionalHeader.SizeOfImage
        mov SizeOfImage,ecx
        mov edi,DllBase   
        mov esi,EP
        movzx edx, byte ptr [esi]
        mov byte ptr [esi],0CCh
        call EP
        invoke ExitProcess,NULL
       
end start




[attachment deleted by admin]

laomms

I think I have found the solution.

[attachment deleted by admin]