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, 
                        shl eax,16
                        mov ax,
                        assume fs:nothing
                        mov eax,fs:[18h]
                        mov eax,
                       
                        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
                                      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 .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 .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

Posted on 2008-06-01 18:52:25 by laomms
GetModuleHandle should do it, though I don't know if it works on Vista.
(http://msdn.microsoft.com/en-us/library/ms683199(VS.85).aspx)

GetModuleHandleEx() is thread-safe, but only works on winxp+
(http://msdn.microsoft.com/en-us/library/ms683200(VS.85).aspx)


Though technically a handle != an address, so this might break in future Windows versions.
If there's a better way to do it, I don't know it.
Posted on 2008-06-02 00:57:43 by iblis
If GetModuleHandle returns an error value instead of a module handle, then that DLL has not yet been loaded into the calling process... use the LoadLibrary or LoadLibraryEx function, and remember that you're responsible for unloading any DLLs that you loaded.
Posted on 2008-06-02 02:08:51 by Homer
guys, laomms wanted to read from module base of another process but he mistakingly tried to read directly instead of using ReadProcessMemory..
I think he deleted his post after finding the "solution...".
Posted on 2008-06-02 09:58:35 by drizz

guys, laomms wanted to read from module base of another process but he mistakingly tried to read directly instead of using ReadProcessMemory..
I think he deleted his post after finding the "solution...".


Pretty lame, but in case someone is searching for the solution to the actual question and comes upon this thread, if you don't trust GetModuleHandle, you can use the PSAPI to do the trick with GetModuleInformation...

invoke GetCurrentProcess
mov , eax
invoke GetModuleHandle, "MyDll.dll"
mov , eax
invoke GetModuleInformation, , , offset modinfo, SIZEOF MODULEINFO


The member lpBaseOfDll will contain the base address of the DLL. You can also use this method with other processes in order to get the base address of their DLLs though you must first obtain a handle using OpenProcess.

Note that the process must have PROCESS_QUERY_INFORMATION and PROCESS_VM_READ rights in order to use GetModuleInformation.

Donkey
Posted on 2008-06-02 23:18:38 by donkey
Would have to question the motives if the DLL didn't belong to the local process.
Posted on 2008-06-03 05:28:19 by Homer
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
        inc esi
        cmp al, 22h
        jnz @b
@next:
        mov al, byte ptr
        inc esi
        cmp al, 20h
        jnz @load
@@:
        mov al, byte ptr
        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,.OptionalHeader.AddressOfEntryPoint
        add eax,DllBase
        mov EP,eax
        mov ecx,.OptionalHeader.SizeOfImage
        mov SizeOfImage,ecx
        mov edi,DllBase 
        mov esi,EP
        movzx edx, byte ptr
        mov byte ptr ,0CCh
        call EP
        invoke ExitProcess,NULL
       
end start
Attachments:
Posted on 2008-06-04 17:57:28 by laomms
I think I have found the solution.

Attachments:
Posted on 2008-06-09 00:31:01 by laomms
What was the problem, then? Missing SeDebugPrivilege?

Iirc PECompact stopped turning that off in recent versions, because it would give compatibility programs with... hm, I think it was some printer or twain drivers, whatever.

I hope you aren't unpacking for nefarious deeds...
Posted on 2008-06-09 17:17:12 by f0dder