El programa rompe al llegar a LoadLibrary

Iniciado por nts94, 14 Marzo 2012, 01:05 AM

0 Miembros y 1 Visitante están viendo este tema.

nts94

Hola a todos, estoy haciendo un pequeño virus (sin ánimo de soltarlo, claro, solo como POC) y tras mucho debuggear con el Olly resulta que me lanza una ACCESS_VIOLATION tras llamar a LoadLibraryA en una función que realiza el mismo trabajo que GetProcAddress pero pasándole en su lugar un CRC32, alguien puede ayudarme? Las pruebas las he hecho en un Win 7 x64. Aquí adjunto el código de la función:


@@get_proc:
; [OnEntry]
; edx => crc32
; ebx => hModule
; [OnExit]
; eax => lpfnApi / NULL (OnError)
assume ebx:ptr IMAGE_DOS_HEADER
push edi
push esi
 push ebp
  mov edi,ebx
  add edi,[ebx].e_lfanew
  assume edi:ptr IMAGE_NT_HEADERS
  mov edi,[edi].OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
  add edi,ebx
   assume edi:ptr IMAGE_EXPORT_DIRECTORY
   xor ecx,ecx
   mov esi,[edi].AddressOfNames
   add esi,ebx
   mov ebp,[edi].NumberOfNames
    @@apiname_loop:
     lodsd
     add eax,ebx
     xchg eax,esi
     push eax ; save AddressOfNames
      push ecx
       call @@strlen
       xchg eax,ecx
       push edx
        call @@crc32
       pop edx
      pop ecx
     pop esi
     cmp eax,edx
     jnz @@not_api_hash
      mov esi,[edi].AddressOfNameOrdinals
      add esi,ebx
      shl ecx,1h
      add esi,ecx
      movzx ecx,word ptr [esi]
      shl ecx,2h
      mov esi,[edi].AddressOfFunctions
      add esi,ebx
      add esi,ecx
      mov eax,dword ptr [esi]
      ; code here to check whether we are being forwarded (does the RVA fall into the .edata?)
      mov ebp,ebx
      add ebp,[ebx].e_lfanew
      assume ebp:ptr IMAGE_NT_HEADERS
      mov ecx,[ebp].OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress ; thanks to Matt Pietrek
      cmp eax,ecx
       jb @@not_forwarded
      add ecx,[ebp].OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].isize
      cmp eax,ecx
       ja @@not_forwarded
      @@get_forwarded:
        pop ebp
         add eax,ebx
         xchg esi,eax
         call @@strlen
         push ecx
         push GMEM_FIXED
         call dword ptr [ebp + delta(f_globalalloc)]
         xchg eax,edi
         push edi ; there could be a bug: if someone makes a fwd api without a dot, the host will crash
         @@:
           lodsb
           stosb
           cmp al,'.'
           jne @@not_dot
            mov eax,'lld'
            stosd
      jmp @@match_dot  
         @@not_dot:
         loop @B
         @@match_dot:
         call dword ptr [ebp + delta(f_loadlibrary)] ; I know the program won't be able to free the library (i don't know yet how ms loader does it)
         push esi
         push eax
         call dword ptr [ebp + delta(f_getprocaddress)]
         push eax
          push edi
          call dword ptr [ebp + delta(f_globalfree)]
         pop eax
         jmp @@fwd_api_found
      @@not_forwarded:
      add eax,ebx
      jmp @@api_found
     @@not_api_hash:
     inc ecx
     cmp ecx,ebp ; I need ecx as a counter
     jbe @@apiname_loop
 @@not_found:
   xor eax,eax
 @@api_found:
   pop ebp
 @@fwd_api_found:
pop esi
  pop edi
  ret




@@strlen:
; [OnEntry]
; esi => [StringA]
; [OnExit]
; eax => Length
xchg esi,edi
xor eax,eax
xor ecx,ecx
dec ecx
push edi
repnz scasb
pop edi
inc ecx
not ecx
xchg eax,ecx
xchg esi,edi
ret


.const
POLYNOM equ 0edb88320h
.code
@@crc32:
; [OnEntry]
; esi => [Mem]
; ecx => count
; [OnExit]
; eax => crc32
xor edx,edx
dec edx
@@crc_loop:
mov eax,edx
and eax,0ffh
xor al,byte ptr [esi]
push ecx
 mov ecx,8h
 @@:
 test al,1h
 jz @@bit_not_set
  shr eax,1h
  xor eax,POLYNOM
  jmp @@bit_continue
 @@bit_not_set:
  shr eax,1h
 @@bit_continue:
 loop @B
pop ecx
inc esi
shr edx,8h
xor edx,eax
loop @@crc_loop
xchg eax,edx
not eax
ret


Tras tracear un poco veo que las llamadas van así:

- LoadLibraryA -> LoadLibraryExA -> KernelBase.749B6DEF -> ntdll.RtlAnsiStringToUnicodeString -> ...



Les agradezco cualquier ayuda/opinión/orientación sobre el tema

PD: Acabo de comprobar que en XP funciona perfectamente, puede ser por algo relacionado con WOW32? O tal vez es por Win7?

Ah, y perdon por un tema/post tan largo, es que no quiero que falte nada de info

Karcrack

Comprueba que no malformas el stack. Ya que LoadLibrary no debería intentar escribir en ningún lado.

nts94

OK, acabo de solucionarlo:

-> Por un lado, debe de haber algun bug/incompatibilidad con el Stealth64 del OllyDbg en Win7,  ya que el Olly del XP no tenía plugins y iba, y al desactivarlo también va en Win7

-> Por el otro, había un pequeño bug en otra parte de mi código que no preservaba el antiguo EDI, y entonces FindNextFileA lo usaba después de haber sido liberado (y por eso tampoco iba fuera del Olly) (en XP SEH me salvaba) XD

En fín, muchas gracias de todas formas.

PD: por cierto, si quereis hacer uso del código o teneis alguna pregunta, no dudeis en postear (pa eso estamos,no?) :)