Jump to content
Tuts 4 You

Nasm dll calling itself.. IAT infinite loop...


opc0d3

Recommended Posts

Hello guys, how are you all ?

I trying to do a PoC about PEB hooking and at this point i just trying to code a dll that receives the call and pass to the original dll.

I have the dlltest2.dll with 3 functions and in the nasm I am exporting these same 3 functions.

I thought that if I did a LoadLibrary with the original the __imp_ would be the original function, but instead the NTDLL is loading my own nasm/dll functions on the IAT making a infinite loop... For example the function NOME goes to the IAT that it forced to ack to the same nasm/NONAME function instead of the dlltest2.dll/NONAME.

I did this piece of code in NASM

[BITS 32]

global _start
global NONAME
global testing_three
global testing_two

[section .drectve info align=8]
    db "kernel32.dll", 0x20

section .idata
	extern __imp_NONAME
	extern __imp_testing_three
	extern __imp_testing_two
    extern __imp_LoadLibraryA
    
section .data
    szdlltest db "dlltest2.dll", 0
    sznewtxt db "NONAME_HOOKED", 0

section .code

    _start:
        push dword szdlltest
        call __imp_LoadLibraryA
        mov eax, 1
        ret 0x12

    NONAME:
        mov [ebp-4], dword sznewtxt
        jmp __imp_NONAME
        retn

    testing_three:
        jmp __imp_testing_three
        retn

    testing_two:
        jmp __imp_testing_two
        retn

Compiled with nasm... and linked with golink..

golink /dll /entry _start /base 0x3a0000 /export NONAME /export testing_three /export testing_two /fo .\dlltest.dll .\export_of.obj .\dlltest2.dll

In this case dlltest2.dll is the original and is different even in size from my NASM/DLL.

I trying to debug the loading process trying to understand why it loads itself on the IAT. 

TO call this function I'm using... 

#include <stdio.h>
#include <windows.h>

//__declspec(dllimport) void NONAME(char *text);
typedef void (*NONAME)(char*);

int main(int args, char** vargs){

    char str[50] = "NONAME_FUNC";
    HANDLE dll;
    NONAME n;
    
    dll = LoadLibrary("dlltest.dll");
    n = (NONAME)GetProcAddress(dll, "NONAME");
    
    n(str);

    return 0;

}

Any ideas ? Thanks!!

EDIT------------

Debugging here i found that in the import dir of my NASM/DLL is:

import_dir.png.d04cd8f78d936201420d5c24c36aeb35.png

And in my calldll.exe module in the memory map the dlltest is already loaded, it seems that the loader already found the dlltest.dll (fake nasm) and link itself:

memory_map.png.273ed0495069acf4582ddac0c0532c26.png

Thats right ? Any ideas to work around it ? I mean, link to the original dll instead of the fake one. Thanks again! :)

Edited by opc0d3
Link to comment

doing a loadlibrary in the dllmain is a bad idea, even documented on msdn...

options you could do

1. start a thread, have the thread do the loadlibrary / init stuff

2. make your functions have an 'init' call that does the loadlibrary if the dll is not resident

3. have the dll import the other dlls via its import table

otherwise you get a deadlock like you've experienced

Link to comment
6 hours ago, evlncrn8 said:

doing a loadlibrary in the dllmain is a bad idea, even documented on msdn...

options you could do

1. start a thread, have the thread do the loadlibrary / init stuff

2. make your functions have an 'init' call that does the loadlibrary if the dll is not resident

3. have the dll import the other dlls via its import table

otherwise you get a deadlock like you've experienced

Interesting.. I think the best options is to steal the export array from the original dll and replace in my IAT on my fake dll. I think it's what you are suggesting in the third option right ?

I trying it now, if can't do it I'll try to load in a thread. I'm not sure how the thread could change the result. But I post my results here after my tries =)

Thank you for your tips and your time, evlncrn8. Best resgards!

Link to comment

thread changes results as it'll be executed / started after the dllmain returns out to the pe loader main routine... and after other dlls have been loaded and so on..

cleanest option i'd say is ..

make your dll (which has the special functions exported)

at the start of each function put an init routine, which does the loadlibrary and init stuff is needed.. and use a spinlock / critical section for this so you dont get any race conditions and such.. once the init is done, then just do what you need to do, call the 'real' function, return with a magic value, whatever..

Link to comment
10 hours ago, evlncrn8 said:

thread changes results as it'll be executed / started after the dllmain returns out to the pe loader main routine... and after other dlls have been loaded and so on..

cleanest option i'd say is ..

make your dll (which has the special functions exported)

at the start of each function put an init routine, which does the loadlibrary and init stuff is needed.. and use a spinlock / critical section for this so you dont get any race conditions and such.. once the init is done, then just do what you need to do, call the 'real' function, return with a magic value, whatever..

I got it now. But the problem is when the dll is loading (fake one) the import directory searches for the dlltest.dll (original one) but the fake is loaded instead, even with my loadlibrary in the entrypoint of dll, the loader already filled the IAT with my own IAT functions given me a DeadLock. 

I'm grasping on calling the Virtualprotect to change the IAT to READ_WRITE. I'm getting 0x57 on GetLastError. =/
eax = IAT

push eax
push 40
push 40
push eax
call VirtualprotectEx

Im changing TO READ_WRITE_EXECUTE and 40 bytes just for test purposes.
I already tried to pass a variable in the lpOldProtect.
Any ideas ?


Can you point to me some tutorial about SpinLock and Threads with ASM ? 
And what would be 'magic value' ?

Thanks for all tips! :)

Edited by opc0d3
Link to comment

thread is just createthread call

easiest option for you without getting messy in asm for spinlock is use enter/leave criticalsection

---

i'd just do it like this...

make your dll, and name it as the target dll.. lets call it redirect.dll

in the dllmain of redirect.dll DO NOTHING

make one routine in redirect.dll that does an entercriticalsection, inits itself, and sets a value in your data section to show init was done.. then leave with a leavecriticalsection... simple

in the init routine you load the real dll you are 'faking' and setup the trampolines for your fake functions

in the redirect.dll you have the functions you are faking so

fake1 function will call the init (which will set things up if it hasnt already), and do what its meant to 

and so on...

 

  • Like 1
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...