flat assembler
Message board for the users of flat assembler.

flat assembler > Projects and Ideas > hash importer

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
hidden



Joined: 14 Feb 2007
Posts: 49
I wasn't sure? where to post it, to the "windows" or to the "macros", because it relative to both, so I post it to the "Projects and Ideas" Smile

It's a procedure, that find functions in the modules by hashes of the names, and generates jmp table with relative jumps to the imported functions.

I could be used in windows applications, dll modules, kernel-mode modules and another PE export compatible files as well.

It's absolutely relative, no need reloc section for drivers and dll's, also it saves memory in big import tables.

Code:
format PE GUI 4.0
entry start

include 'win32w.inc'

AntiDebug equ ; It's more difficult to debug, then jumps goes not to the begin of the function. But any way OllyDbg doesn't show it as usual.

macro rol32 op1, op2
  match =dword v, op1 \ v = v shl op2 or v shr 32 - op2 and $FFFFFFFF \
   match =word v,  op1 \ v = v shl op2 or v shr 32 - op2 and $FFFFFFFF \
   match =byte v,  op1 \ v = v shl op2 or v shr 32 - op2 and $FFFFFFFF \ 

macro iprc proc, name
  forward
    if used proc | impanyway eq
     if name eqtype ''
      local ch
      local hash
      local length
      virtual at 0
       db name
       length = $
       hash = 0
       repeat length
        load ch byte from length-%
        rol32 dword hash, 5
        hash = hash xor ch and 11111b
       end repeat
      end virtual
      label proc dword
      db length ; Length, if $ff then load lib, if $fe then end, if $fd then by id
      dd hash
     else
      db $fd
      dd name+1
     end if
    end if 

macro iprcex proc
  forward
    if used proc | proc eq LoadLibraryA | impanyway eq
      local ch
      local hash
      local length
      virtual at 0
       db `proc#''
       length = $
       hash = 0
       repeat length
        load ch byte from length-%
        hash = hash shl 5 or hash shr 32 - 5 and $FFFFFFFF ; hash = hash rol 5
        hash = hash xor ch and 11111b
       end repeat
      end virtual
      virtual at $
       proc dd ?
      end virtual
      db length ; Length, if $ff then load lib, if $fe then end, if $fd then by id
      dd hash
    end if 

macro hip proc, len, hash
  forward
    if used proc | proc eq LoadLibraryA | impanyway eq
     proc db len
          dd hash
    end if 

macro imod module, str
  forward
    db $fe
    module dd module#.str - $
    module#.text equ str 

macro istr module
  forward
    module#.str db module#.text, 0 

macro endi ierrproc
  db $ff 

struct IED
 Characteristics        dd ? ;This field appears to be unused and is always set to 0.
 TimeDateStamp          dd ? ;The time/date stamp indicating when this file was created.
 Version                dd ? ;These fields appear to be unused and are set to 0.
 Name                   dd ? ;The RVA of an ASCIIZ string with the name of this DLL.
 Base                   dd ? ;The starting ordinal number for exported functions. For example, if the file exports functions with ordinal values of 10, 11, and 12, this field contains 10. To obtain the exported ordinal for a function, you need to add this value to the appropriate element of the AddressOfNameOrdinals array.
 NumberOfFunctions      dd ? ;The number of elements in the AddressOfFunctions array. This value is also the number of functions exported by this module. Theoretically, this value could be different than the NumberOfNames field next, but actually they're always the same.
 NumberOfNames          dd ? ;The number of elements in the AddressOfNames array. This value seems always to be identical to the NumberOfFunctions field, and so is the number of exported functions.
 AddressOfFunctions     dd ? ;This field is an RVA and points to an array of function addresses. The function addresses are the entry points RVAs for each exported function in this module.
 AddressOfNames         dd ? ;This field is an RVA and points to an array of string pointers. The strings are the names of the exported functions in this module.
 AddressOfNameOrdinals  dd ? ;This field is an RVA and points to an array of WORDs. The WORDs are the export ordinals of all the exported functions in this module. However, don't forget to add in the starting ordinal number specified in the Base field.
ends

; ZF - Error, ax - Error code

AX_WRONG_MODULE_HANDLE  equ 'MZ'
AX_WRONG_PE_SECTION     equ 'PE'
AX_WRONG_EXPORT_SECTION equ 'WE'
AX_NO_EXPORT_SECTION    equ 'NE'
AX_FUNCTION_NOT_FOUND   equ 'NF'

MAX_MOD_MODULE_NAME_LEN = 260

proc ProcIdByHash, base, hash, len
        ;local   img_size dd ?
        local   exp_addr dd ?
        local   exp_end dd ?
        xchg    edi, base
        push    ebx ecx edx esi

        mov     ax, 'MZ'
        cmp     edi, ax
        jnz     .default_error

        mov     edx, edi+$3C ; OffSet to PE Header

        mov     ax, 'PE'
        cmp     edi+edx, ax
        jnz     .default_error

        ;mov     eax, edi+edx+$50 ; Image size
        ;mov     img_size, eax

        mov     ebx, edi+edx+$78 ; Offset to Export section
        mov     eax, edi+edx+$7C ; Size of Export section
        add     eax, ebx

        cmp     al, sizeof.IED ; Is export table presents
        jb      .noexport
        test    ebx, ebx ; Is export table presents
        jz      .noexport
        cmp     eax, edi+edx+$50 ; Is end of export table in image
        ja      .err_wrong_export
        cmp     ebx, edi+edx+$50 ; Is export table in image
        ja      .err_wrong_export

        mov     exp_end, eax
        mov     exp_addr, ebx

        mov     ecx, edi+ebx+IED.NumberOfNames
        mov     ebx, edi+ebx+IED.AddressOfNames

        test    ecx, ecx ; Any name
        jz      .noexport
        test    ebx, ebx
        jz      .noexport
        cmp     ebx, exp_end
        ja      .err_wrong_export
        lea     eax, ebx+ecx*4
        cmp     eax, exp_end ; Is last name in export table
        ja      .err_wrong_export

        lea     ebx, edi+ebx-4

  .next_export_item
        mov     esi, ebx+ecx*4
        cmp     esi, exp_end
        ja      .err_wrong_export

        movsx   eax, bytelen
        add     eax, esi
        cmp     eax, exp_end
        ja      .wrng_length
        cmp     byteeax+edi, 0
        jne     .wrng_length

        add     esi, edi
        mov     edx, hash

  @@   lodsb
        test    al, al
        jz      @f
        and     al, 11111b
        xor     dl, al ; Hashing
        ror     edx, 5
        jmp     @b

  @@   test    edx, edx
        jz      .hash_found

  .wrng_length
        loop    .next_export_item

        mov     ax, 'NF'
        jmp     .default_error

  .hash_found
        mov     ebx, exp_addr
        lea     eax, ebx+IED.AddressOfNameOrdinals
        cmp     eax, exp_end
        ja      .err_wrong_export
        mov     eax, edi+eax
        cmp     eax, exp_end
        ja      .err_wrong_export
        lea     eax, eax+ecx*2-2
        cmp     eax, exp_end
        ja      .err_wrong_export
        movzx   eax, wordeax+edi
        ;add     eax, edi
        ;movzx   eax, wordeax+ecx*2-2
        add     eax, edi+ebx+IED.Base

        test    eax, eax

  .end pop     esi edx ecx ebx
        mov     edi, base
        ret

  .err_wrong_export
        mov     ax, 'WE'

  .default_error
        xor     ebx, ebx
        jmp     .end

  .noexport
        mov     ax, 'NE'
        jmp     .default_error
endp

proc ProcAddrById, base, id
        local   exp_end dd ?
        xchg    edi, base
        push    ebx edx ecx esi

        mov     ecx, edi+$3C ; OffSet to PE Header

        mov     ebx, edi+ecx+$78 ; Offset to Export section
        mov     eax, edi+ecx+$7C
        cmp     ebx, edi+ecx+$50
        ja      .err_wrong_export
        add     eax, ebx
        mov     exp_end, eax
        mov     esi, edi+ebx+IED.AddressOfFunctions
        mov     eax, id
        sub     eax, edi+ebx+IED.Base

        lea     eax, esi+eax*4
        cmp     eax, exp_end
        ja      .err_wrong_export

        mov     esi, edi+eax ; RVA of function
        lea     eax, esi+edi

        cmp     esi, edi+$50 ; Is this proc in image
        ja      .err_wrong_export

        cmp     esi, ebx
        jb      .proc_found
        cmp     esi, exp_end
        ja      .proc_found

  ; If you don't need Forwarded Export Support you can comment next block
        stdcall GetForwardedProcId, eax
        stdcall ProcAddrById, edi, eax
        jmp     .end
  ; End of block

  .err_wrong_export
        xor     ebx, ebx
        mov     ax, 'WE'
        jmp     .end

  .proc_found
        test    eax, eax

  .end
        pop     esi ecx edx ebx
        mov     edi, base
        ret
endp

proc GetForwardedProcId, str
        mov     esi, str

        mov     ecx, MAX_MOD_MODULE_NAME_LEN
        sub     esp, ecx

        mov     edx, esp

        mov     ebx, esi
  .next_simbol
        lodsb

        cmp     al, '.'
        jne     @f
        mov     ebx, esi
@@
        mov     edx, al
        inc     edx

        or      al, al
        jz      @f

        loop    .next_simbol
@@
        cmp     ebx, str
        jz      .GetProc

        lea     eax, esp+ebx
        sub     eax, str
        mov     byteeax-1, 0
        stdcall LoadLibraryA, esp
        mov     edi, eax

.GetProc
        add     esp, MAX_MOD_MODULE_NAME_LEN

        mov     esi, ebx
        neg     ebx

        xor     edx, edx

@@     lodsb
        or      al, al
        jz      @f
        and     al, 11111b
        xor     dl, al
        ror     edx, 5
        jmp     @b
@@
        lea     ebx, ebx+esi-1

        lea     ecx, ebx*5
        rol     edx, cl

        stdcall ProcIdByHash, edi, edx, ebx

        ret
endp

proc GetKernel
        xor     eax, eax
        mov     eax, fseax+30h
        test    eax, eax
        js      ngk
        mov     eax, eax+0Ch
        mov     esi, eax+1Ch
        lodsd
        mov     eax, eax+8
        jmp     egk
ngk    mov     eax, eax+34h
        add     eax, 7Ch
        mov     eax, eax+3Ch
egk    ret
endp

proc BaseByAddr, addr
        mov     eax, addr

        xor     ax, ax
  @@   cmp     wordeax, 'MZ'
        jz      @f
        sub     eax, $10000
        jmp     @b
  @@   ret
endp

proc importer, kernel, imports, loadlib, errproc
        xchg    esi, imports
        xchg    edi, kernel

  .looplodsb
        cmp     al, $fd
        ja      .more
        je      .byid
        mov     ah, al

        or      edi, edi
        jz      .xxx

        stdcall ProcIdByHash, edi, esi, esi-1
        jnz     @f
        cmp     ax, 'NF'
        jnz     .endi
        mov     eax, errproc
        test    eax, eax
        jnz     .stor
        mov     ax, 'NF'
        jmp     .endi
  @@
  .gbi stdcall ProcAddrById, edi, eax
        jnz     @f
        mov     eax, errproc
        test    eax, eax
        mov     ax, 'WE'
        jnz     @f
        jmp     .endi
  @@

  .storif      AntiDebug eq
         cmp     wordeax, $FF8B
         jnz     @f
         add     eax, 2
  @@   end     if
         sub     eax, 4

  @@   sub     eax, esi
        mov     byteesi-1, $E9
        mov     dwordesi, eax
  .xxx lodsd
        jmp     .loop

  .byidmov     eax, esi
        jmp     .gbi

  .morecmp     al, $fe
        ja      .endi
        lodsd

        lea     eax, eax+esi-4
        invoke  loadlib, eax
        mov     edi, eax
        mov     esi-4, eax

        jmp     .loop

  .endimov     edi, kernel
        mov     esi, imports
        ret
endp

proc ImportErrProc
        stdcall MessageBoxA, 0, wfmsg, wferr, MB_ICONERROR
        ret
endp

myi
  iprc LoadLibraryA, 'LoadLibraryA',\
    AddVectoredExceptionHandler,'AddVectoredExceptionHandler',\
    ExitProcess,'ExitProcess'
  imod user, 'user32'
  iprcex MessageBoxA,\ ; iprcex if a simbol equal to the name
    WrongFunc
  endi

 xxx = AddVectoredExceptionHandler

start
        stdcall BaseByAddr, esp
        ;stdcall GetKernel
        stdcall importer, eax, myi, LoadLibraryA, ImportErrProc
        jz      Error
        stdcall WrongFunc ; Example of wrong function

        stdcall MessageBoxA, 0, txt, txt, 0

exit   stdcall ExitProcess, 0
        ret

Error  mov     wordwferr, ax
        stdcall MessageBoxA, 0, wferr, wferr, 0
        jmp     exit

txt             db "It works",0
wferr           db '   Error',0
wfmsg           db "You'r trying to call wrong function, if it has any arguments then process needs to be restarted.",0
        istr    user    


I thick somebody may find it useful Smile

And some more, macro emulation of rol, rol sometimes very useful

[+] Support forwarding functions. (If anything wrong with it please let me know)
[+] If something wrong with module or export tables and errproc = 0 it return error codes, otherwise it call errproc instead of undefined function.

Remark:
1) LoadLibraryA should be imported or declared before using "imod" or Forwarding functions, better if it is first this to do.
2) Import table should be in writable executable section, but "istr" can be in read only section.

Updates:
Added passing needed functions by arguments of importer.


Description: The same code, that listed.
Download
Filename: 111.ASM
Filesize: 9.63 KB
Downloaded: 330 Time(s)


_________________
Image Lang: (eng|рус)


Last edited by hidden on 08 Mar 2007, 20:31; edited 6 times in total
Post 02 Mar 2007, 20:18
View user's profile Send private message Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3170
Location: Denmark
Have you done extensive collision testing of this?
Post 04 Mar 2007, 12:24
View user's profile Send private message Visit poster's website Reply with quote
hidden



Joined: 14 Feb 2007
Posts: 49
Quote:
Have you done extensive collision testing of this?

Heshes isn't case sensitive, it uses only first 5 bits of the symbol nomber, and understend 0 as p, 1 as q, 2 as r and so on.
Hashes will be 100% different if name not longer then 6 ascii simbols, it is theoretically, but practically I didn't find any api function with same hash, but to be sure I added also length of the name.

It works just fine for me.
Post 04 Mar 2007, 19:22
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7108
Location: Slovakia
hidden: that means it doesn't work good enough. You must somehow ensure case when two functions have same hash.

By the way, it is pretty possible to have first 6 chars of 2 different functions same, because many names are prefixed with abbreviation of brand the provide, sometimes just the has abbreviation has 6 chars Smile


Last edited by vid on 04 Mar 2007, 19:37; edited 1 time in total
Post 04 Mar 2007, 19:33
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
okasvi



Joined: 18 Aug 2005
Posts: 383
Location: Finland
Nice macros&procedures Smile


edit:
Quote:
By the way, it is pretty possible to have first 6 chars of 2 different functions same, because all names are prefixed with abbreviation of brand the provide, sometimes just the has abbreviation has 6 chars


crc32 should be enough.
Post 04 Mar 2007, 19:34
View user's profile Send private message MSN Messenger Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7108
Location: Slovakia
okasvi: still it's not really the best way to leave door open for bugs that may appear long time ago
Post 04 Mar 2007, 19:39
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3170
Location: Denmark
You should at least check the hashing scheme on all exports of all DLLs in %windir%\system32 - any collision == use another hash algo.
Post 04 Mar 2007, 19:44
View user's profile Send private message Visit poster's website Reply with quote
okasvi



Joined: 18 Aug 2005
Posts: 383
Location: Finland
Btw. does this support forwarded exports? If it doesnt it should be noted in first post.
My personal getprocaddr with hashing doesnt, and I first ran into some problems while figuring why it doesnt work on some apis but since I'm the only user of it, it doesnt matter.
Post 04 Mar 2007, 20:01
View user's profile Send private message MSN Messenger Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3170
Location: Denmark
Not only do you need to support forwarded exports to be able to handle just about any real program running on NT, you also need to handle data exports if you want to support anything linked against dynamic MSVCRT.
Post 04 Mar 2007, 20:05
View user's profile Send private message Visit poster's website Reply with quote
hidden



Joined: 14 Feb 2007
Posts: 49
No, it doesn't support forwarded exports, I don't see an easy way to recognize, is it offset to the function or name to another exports and even if I recognize, I'll have to import that item, and this function would be 3 times bigger. Isn't it more easy to check that function forwarded or not, before using it?

It will make jumps to the data variables, so you will ether need to decompile jumps or use ProcIdByHash, ProcAddrById functions separately, to get adders to the variable.

Quote:
By the way, it is pretty possible to have first 6 chars of 2 different functions same, because many names are prefixed with abbreviation of brand the provide, sometimes just the has abbreviation has 6 chars Smile
chars that after char 6 will be XORed by previous chars.
CreateDialogIndirect & CreateDialogIndirectParam will have different hashes also it checks sizes.

Quote:
use another hash algo
I use this algo because it needs only dword/hash

Algo:
Code:
01100-01111-00001-00100-01100-01001-00 xor 010-10010-00001-10010-11001-00001-0000
  L     o     a     d     L     i       b        r     a     r     y     A
    


And then XOR this 2 dwords, it's hash of "LoadLibraryA"


Last edited by hidden on 04 Mar 2007, 23:04; edited 1 time in total
Post 04 Mar 2007, 22:59
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7108
Location: Slovakia
You still missed the most important part:
Quote:
that means it doesn't work good enough. You must somehow ensure case when two functions have same hash.
Post 04 Mar 2007, 23:02
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3170
Location: Denmark
A data export can be recognized by checking if export RVA is inside a section with PE_SCN_CNT_INITIALIZED_DATA - at least that seems to work, I haven't checked how NT itself handles it.

And forwarded functions could change with a service pack, not to mention that some forwarded functions are useful. I detect a forward by checking if the export RVA lies within PE_DIRENT_EXPORT.rva and PE_DIRENT_EXPORT.size bytes forward - again, dunno how NT itself handles it.
Post 04 Mar 2007, 23:14
View user's profile Send private message Visit poster's website Reply with quote
hidden



Joined: 14 Feb 2007
Posts: 49
Here is some more macros&function - Exception handler, I didn't tested it enough, but it works.

Code:
macro SetHandler
 push TryHandler
  push dwordfs0
  mov fs0, esp
  push __EXCEPT
  push ebp 

macro UnsetHandler
 pop dwordfs0
  add esp, 4 

macro try
 __TRY equ
  local ..endt
  __ENDT equ ..endt
  local ..except
  __EXCEPT equ ..except
  SetHandler 

macro except
 add esp, 8
  UnsetHandler
  jmp __ENDT
  __EXCEPT
  UnsetHandler
  restore __TRY
  __TRY equ , 

macro endt
 if __TRY eq
    add esp, 8
    __EXCEPT
    UnsetHandler
  end if
  __ENDT
  restore __EXCEPT
  restore __ENDT
  restore __TRY 

macro TryProc
 proc TryHandler, ExceptionRecord, EstablisherFrame, ContextRecord, DispatcherContext
    push esi edi ebx
    mov esi, EstablisherFrame
    mov edi, ContextRecord
    mov ebx, esi
    sub esi, 8
    add edi, $B4
    movsd ; ebp
    lodsd
    xchg edi, eax
    ;movsd ; eip
    mov edi+12, ebx ; esp
    mov edi-8, eax ; esp

    pop ebx edi esi
    xor eax, eax
    ret
  endp 

if noinit eq
else
  TryProc
end if    

Quote:
You must somehow ensure case when two functions have same hash.

Quote:
You should at least check the hashing scheme on all exports of all DLLs in %windir%\system32 - any collision == use another hash algo.

And my try to check collisions:
Code:
format PE GUI 4.0
entry start

include 'win32a.inc'
include 'P\fasm\asm\tests\utils.inc'

MAX_PATH = 260

struct WIN32_FIND_DATA
  dwFileAttributes      dd ?
  ftCreationTime        dq ?
  ftLastAccessTime      dq ?
  ftLastWriteTime       dq ?
  nFileSizeHigh         dd ?
  nFileSizeLow          dd ?
  dwReserved            dq ?
  cFileName             rb MAX_PATH
  cAlternateFileName    rb 14
ends

myi
  iprcex LoadLibraryA, VirtualAlloc
  iprcex ExitProcess, LoadLibraryExA, FreeLibrary, FindFirstFileA, FindNextFileA
  imod user, 'user32'
  iprcex MessageBoxA
  endi
  istr user

  start
        stdcall GetKernel
        stdcall importer, eax, myi

        stdcall VirtualAlloc, 0, $10000, MEM_COMMIT, PAGE_READWRITE
        mov     buf, eax

        stdcall FindFirstFileA, mask, ffd
        mov     hfind, eax
.loop
  try
        mov     edi, buf
        stdcall LoadLibraryExA, ffd.cFileName, 0, LOAD_LIBRARY_AS_DATAFILE
        cmp     eax, 1
        jb      @f
        xor     si, si
        xchg    si, ax
        mov     ebp, eax

        call    HashAllNames ; base - ebp

        call    CompareHashes
@@
  endt
        jz      Found

        stdcall FreeLibrary,  ebp

.next  stdcall FindNextFileA, hfind, ffd
        test    eax, eax
        jnz     .loop

        stdcall MessageBoxA, 0, sNothingFound, sNothingFound, 0

@@     stdcall ExitProcess,-1

 Found
        stdcall MessageBoxA, 0, sFoundCollision, sFoundCollision, 0
        jmp     @b

proc CompareHashes
        xor     edx, edx
@@     inc     edx
        lea     edi, edx*4
        add     edi, buf
        mov     ecx, count
        sub     ecx, edx
        jecxz   @f
        mov     eax, edi-4
        repne   scasd
        jne     @b
        ret
@@     cmp     cl, 1 ; unset ZF
        ret
endp

proc HashAllNames
        pushad

        cmp     wordebp, 'MZ'
        jne     .wrong
        mov     eax, ebp+$3C ; OffSet to PE Header
        cmp     wordebp+eax, 'PE'
        jne     .wrong
        mov     ebx, ebp+eax+$78 ; Offset to Export section
        test    ebx, ebx
        jz      .wrong
        add     eax, ebp

        test    si, si
        jz      .running
        xor     edx, edx
@@     mov     ecx, eax+edx+$100 ; Virtual Size of the first section
        add     ecx, eax+edx+$104 ; Virtual Address of the first section
        cmp     ebx, ecx
        jb      @f
        add     edx, $28
        jmp     @b
@@     sub     ebp, eax+edx+$104 ; Section offset in the file
        add     ebp, eax+edx+$10C ; Virtual Address of the first section
.running

        mov     ecx, ebp+ebx+IED.NumberOfNames
        test    ecx, ecx
        jz      .wrong
        mov     ebx, ebp+ebx+IED.AddressOfNames
        test    ebx, ebx
        jz      .wrong
        add     ebx, ebp

        mov     count, ecx

.loop  mov     esi, ebx
        add     esi, ebp

        mov     edx, esi
        sub     edx, ebp
        and     edx, $7FFFFFFF
        cmp     edx, 10*1024*1024
        ja      .wrong

        xor     edx, edx
@@     lodsb
        or      al, al
        jz      @f
        and     al, 11111b
        xor     dl, al
        ror     edx, 5
        jmp     @b
@@
        mov     edi, edx
        add     edi, 4

        add     ebx, 4
        dec     ecx
        jnz     .loop

.wrong
        popad
        ret
endp

sFoundCollision db 'Collision has been found',0
sNothingFound   db 'Collision not found',0

mask            db 'C\windows\system32\*.dll',0

count           dd ?
buf             dd ?
hfind           dd ?
ffd             WIN32_FIND_DATA    

Result: Collision not found
Post 05 Mar 2007, 06:13
View user's profile Send private message Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3170
Location: Denmark
Good Smile

_________________
Image - carpe noctem
Post 05 Mar 2007, 13:59
View user's profile Send private message Visit poster's website Reply with quote
hidden



Joined: 14 Feb 2007
Posts: 49
Quote:
how NT itself handles it.
I've reversed ntdll.LdrGetProcedureAddress and found out that forwarding functions can be done only to the ntdll, so if something forwarding somewhere, it forwarding to the ntdll.
If you put "Hardware Access Break Point" at the last "L" on the "NTDLL.RtlAddVectoredExceptionHandler" and try to call GetProcAddress(kernel, 'AddVectoredExceptionHandler'), you will stop at the algo that checks it.
Post 05 Mar 2007, 16:33
View user's profile Send private message Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3170
Location: Denmark
can be done only to NTDLL, or is only done to NTDLL? I haven't seen any other redirects, but it would be silly if there was an arbitrary restriction like that?
Post 05 Mar 2007, 23:32
View user's profile Send private message Visit poster's website Reply with quote
hidden



Joined: 14 Feb 2007
Posts: 49
Quote:
can be done only to NTDLL, or is only done to NTDLL?
Right, "is", I have read some MSDN, I will check what can I do with forwarding...

_________________
Image Lang: (eng|рус)
Post 06 Mar 2007, 00:49
View user's profile Send private message Reply with quote
hidden



Joined: 14 Feb 2007
Posts: 49
I added Support forwarding functions, it needs tests and it can be easily disabled by commenting little block. Smile

Also I converted "Collisions Checker" to API extractor Smile
Code:
format PE GUI 4.0
entry start

include 'win32a.inc'
include 'P\fasm\asm\tests\utils.inc' ; - hash importer

FILE_WRITE_DATA = 2

myi
  iprcex AddVectoredExceptionHandler, LoadLibraryA, VirtualAlloc
  iprcex ExitProcess, LoadLibraryExA, FreeLibrary, CreateFileA, WriteFile, CloseHandle
  imod _user, 'user32'
  iprcex MessageBoxA
  endi
  istr _user

kernel          db 'kernel32',0
kernel_txt      db 'kernel32.inc',0
user            db 'user32',0
user_txt        db 'user32.inc',0
gdi             db 'gdi32',0
gdi_txt         db 'gdi32.inc',0
shell           db 'shell32',0
shell_txt       db 'shell32.inc',0
shlwapi         db 'shlwapi',0
shlwapi_txt     db 'shlwapi.inc',0
advapi          db 'advapi32',0
advapi_txt      db 'advapi32.inc',0

  start
        stdcall GetKernel
        stdcall importer, eax, myi

        stdcall VirtualAlloc, 0, $10000, MEM_COMMIT, PAGE_READWRITE
        mov     buf, eax

        mov     esi, kernel
        mov     edi, kernel_txt
        call    GetModImports

        mov     esi, user
        mov     edi, user_txt
        call    GetModImports

        mov     esi, gdi
        mov     edi, gdi_txt
        call    GetModImports

        mov     esi, shell
        mov     edi, shell_txt
        call    GetModImports

        mov     esi, shlwapi
        mov     edi, shlwapi_txt
        call    GetModImports

        mov     esi, advapi
        mov     edi, advapi_txt
        call    GetModImports


        stdcall MessageBoxA, 0, sDone, sDone, 0

@@     stdcall ExitProcess, -1

 .err  stdcall MessageBoxA, 0, sError, sError, 0
        jmp     @b

proc GetModImports
        stdcall LoadLibraryExA, esi, 0, LOAD_LIBRARY_AS_DATAFILE
        cmp     eax, 1
        jb      @f
        mov     ebp, eax
        call    HashAllNames ; base - ebp
@@     stdcall FreeLibrary,  ebp
        stdcall CreateFileA, edi, FILE_WRITE_DATA, FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0
        push    eax
        stdcall WriteFile, eax, buf, count, esp, 0
        stdcall CloseHandle
        ret
endp

proc HashAllNames
        pushad

        xor     si, si
        xchg    si, bp

        cmp     wordebp, 'MZ'
        jne     .wrong
        mov     eax, ebp+$3C ; OffSet to PE Header
        cmp     wordebp+eax, 'PE'
        jne     .wrong
        mov     ebx, ebp+eax+$78 ; Offset to Export section
        test    ebx, ebx
        jz      .wrong
        add     eax, ebp

        test    si, si
        jz      .running
        xor     edx, edx
@@     mov     ecx, eax+edx+$100 ; Virtual Size of the first section
        add     ecx, eax+edx+$104 ; Virtual Address of the first section
        cmp     ebx, ecx
        jb      @f
        add     edx, $28
        jmp     @b
@@     sub     ebp, eax+edx+$104 ; Section offset in the file
        add     ebp, eax+edx+$10C ; Virtual Address of the first section
.running

        mov     edx, ebp+ebx+IED.NumberOfNames
        test    edx, edx
        jz      .wrong
        mov     ebx, ebp+ebx+IED.AddressOfNames
        test    ebx, ebx
        jz      .wrong
        add     ebx, ebp

        mov     edi, buf

.loop  mov     esi, ebx
        add     esi, ebp

        mov     ecx, esi
        sub     ecx, ebp
        and     ecx, $7FFFFFFF
        cmp     ecx, 10*1024*1024
        ja      .wrong

        mov     eax, 'hip '
        stosd

        xor     ecx, ecx
@@     lodsb
        or      al, al
        jz      @f
        stosb
        and     al, 11111b
        xor     cl, al
        ror     ecx, 5
        jmp     @b
@@
        sub     esi, ebp
        sub     esi, ebx ; esi - length
        lea     eax, esi-1

        mov     esi, ecx
        lea     ecx, eax*5
        rol     esi, cl
        mov     ecx, esi

        call    db2str
        shl     eax, 16
        mov     ax, ',$'
        stosd

        rol     ecx, 8
        xor     ah, ah
        mov     al, cl
        call    db2str
        shl     eax, 16
        mov     ax, ',$'
        stosd

        rol     ecx, 16
        xor     ah, ah
        mov     al, cl
        call    db2str
        shl     eax, 16

        xor     ah, ah
        mov     al, ch
        call    db2str
        stosd

        mov     eax, $0A0D0000

        rol     ecx, 8
        xor     ah, ah
        mov     al, cl
        call    db2str
        stosd

        add     ebx, 4
        dec     edx
        jnz     .loop

        sub     edi, buf
        mov     count, edi

.wrong
        popad
        ret
endp

proc db2str ; ax - input/output
        ror     ax, 4
        shr     ah, 4
        add     ax, '0' shl 8 + '0'
        cmp     al, '9'
        jna     @f
        add     al, 'A' - '9' - 1
@@     cmp     ah, '9'
        jna     @f
        add     ah, 'A' - '9' - 1
@@     ret
endp

sError          db 'Some Error',0
sDone           db 'Done',0

count           dd ?
buf             dd ?    

Than you can use importer like this:
Code:
format PE GUI 4.0
entry start

include 'win32a.inc'
include 'P\fasm\asm\tests\utils.inc'

myi
  include 'kernel32.inc'
  imod user, 'user32'
  include 'user32.inc'
  endi
  istr user

start
        stdcall GetKernel
        stdcall importer, eax, myi

        stdcall MessageBoxA, 0, sWorks, sWorks, 0

        stdcall ExitProcess, -1

 sWorks         db 'It works!!!',0    
Post 06 Mar 2007, 03:23
View user's profile Send private message Reply with quote
Vasilev Vjacheslav



Joined: 11 Aug 2004
Posts: 392
hidden, why you don't create one simple archive which contains you work attached to the first post?
Post 06 Mar 2007, 14:43
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7108
Location: Slovakia
hidden: so, if once there will be some collision, how will your app beheave?
Post 06 Mar 2007, 14:59
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2019, Tomasz Grysztar.

Powered by rwasa.