Results 1 to 2 of 2
  1. #1
    TrollerCoaster's Avatar
    Join Date
    Sep 2010
    Gender
    male
    Location
    I am a fish
    Posts
    633
    Reputation
    61
    Thanks
    800

    Lightbulb [FASM/C/Windows]Importing libraries without any IATs (good for hacks)

    IAT = Import Address Table

    When I first decided to share this, I didn't know whether to release it under the Assembly/C or Tutorial section since it is mostly source code, but I am also trying to show a concept that CAN be ported to some other languages. So, I've decided to put it in the tutorial section.

    As you may know, when you launch a program through Windows API, it automatically reads and parses the headers of the executable. This tutorial will teach you how to avoid adding an "import" (.idata) section. This can also be done easily in C, which I show later.

    First off, a little background on the Windows API. Windows API has a segment for itself that contains procedures of the Windows environment itself. It is loaded into register FS. It contains kernel information, system call tables, etc. Since we can access this register freely within a program, it is possible to call some Windows API functions loading a single library (pure assembly!). However, this destroys your compatibility rating with other Windows systems. Some addresses in the API, though, are standard across Windows systems, so you should feel free to use them at your discretion.

    So let's get down to the nitty gritty...

    Requirements:
    1. Windows OS (tested on an x64 Windows 7 machine)
    2. Brain
    3. Knowledge of Assembly/Machine Language (and you may NEED to use it depending on the language)



     

    All programs loaded through Windows API are automatically loaded with ntdll.dll (Core system functions), kernel32.dll (Windows "kernel"), and KERNELBASE.DLL (Another Windows "kernel"). These libraries can actually be accessed without having to load them through an import table, with the power of Windows API (Sometimes it shines, sometimes it just flat out sucks... Mostly the second part).

    Basically we're going to create an importer by getting LoadLibraryExA from KERNELBASE.DLL (It doesn't have LoadLibraryA).

    First step is to get the base address of either Kernel32.dll or KERNELBASE.DLL. We can get KERNELBASE.DLL with the Windows API.
    Code:
    GetKERNELBASE:
    	mov eax,[fs:0x30]
    	mov eax,[eax+0x0c]
    	mov eax,[eax+0x1c]
    	mov eax,[eax]
    	mov eax,[eax+0x08]
    	ret
    This function gets the base address of KERNELBASE.DLL in your application through a series of Windows API pointers.

    Next we need to create our own GetProcAddress function.
    Code:
    MyGetProcAddress:
    	push ebp
    	mov ebp,esp
    	push ebx
    	push ecx
    	push esi
    	push edi
    	mov dword eax,[ebp+8]
    	mov [.modb],eax ;Get module base address
    	mov dword eax,[ebp+12] ;String to cmp
    	mov [.fname],eax
    	mov eax,[.modb]
    	add eax,60
    	mov eax,[eax] ;get e_lfanew
    	add eax,[.modb] ;PE Header
    	add eax,0x78 ;now points to export directory address
    	mov eax,[eax] ;... and get that address
    	add eax,[.modb]
    	mov [.ied],eax
    	mov ebx,[eax+24] ;get the number of names
    	mov [.non],ebx
    	mov ebx,[eax+28] ;get the addresses of functions
    	mov [.aof],ebx
    	mov ebx,[eax+32] ;get the addresses of names
    	mov [.aon],ebx
    	mov ebx,[eax+36] ;get the addresses of name ordinals
    	mov [.aono],ebx
    
    	xor ecx,ecx
    	.loop:
    	mov dword esi,[.fname]
    	cmp dword ecx,[.non]
    	jnl .break
    	mov dword ebx,[.aon]
    	add dword ebx,[.modb]
    	mov eax,4
    	mul ecx
    	add ebx,eax
    	mov dword ebx,[ebx]
    	add ebx,[.modb]
    	mov edi,ebx
    	.chkstr:
    	cmpsb
    	jne .continue
    	cmp byte [esi-1],0
    	jne .chkstr
    	cmp byte [edi-1],0 ;checking edi isn't necessary, but it's here for safety anyway
    	jne .chkstr
    	mov dword ebx,[.aono]
    	add dword ebx,[.modb]
    	mov eax,2
    	mul ecx
    	add ebx,eax
    	mov word bx,[ebx]
    	mov [.ordinal],bx
    	mov ebx,[.aof]
    	add dword ebx,[.modb]
    	mov eax,4
    	mul [.ordinal]
    	add ebx,eax
    	mov eax,[ebx]
    	add eax,[.modb]
    	pop edi
    	pop esi
    	pop ecx
    	pop ebx
    	mov esp,ebp
    	pop ebp
    	ret 8
    	.continue:
    	inc ecx
    	jmp .loop
    	.break:
    	popa
    	mov esp,ebp
    	pop ebp
    	ret 8
    
    	.modb dd 0
    	.ordinal dw 0
    	.fname dd 0
    	.ied dd 0
    	.non dd 0
    	.aon dd 0
    	.aono dd 0
    	.aof dd 0
    There is a lot of code and I don't feel like explaining it all, but I can explain how to create your own GetProcAddress function (in not too much detail). WARNING: If you don't have a working knowledge of Windows headers, then you will not understand the following steps.
     

    1. Maneuver through the MZ/PE headers of the passed base address of the module to get the export data address.
    2. Get the number of names, addresses of names tables, addresses of name ordinals table, and the addresses of functions table from the export data.
    3. Make your own string comparer to compare the passed procedure string and each of the names in the addresses of names table (Remember: The goal is to not use import tables).
    4. Once you've found the matching string, get the address of the name ordinal to get the function pointer in the addresses of functions table.
    5. Clean up and return the function pointer.

    NOTE: You will need to keep adding the base address of the module to any addresses/data you retrieve from the DLL module.


    Now you can just call the code like so:
    Code:
    call GetKERNELBASE ;puts base address of KERNELBASE.DLL into eax
    
    push <ProcString>
    push <BaseModuleAddress>
    call MyGetProcAddress ;puts address of process <ProcString> from <BaseModuleAddress> into eax
    Here is a full example script:
    Code:
    format PE GUI
    entry main
    
    section '.text' code writable readable executable
    
    k32:
    	dd 0
    	.LoadLibraryEx dd 0
    
    u32:
    	dd 0
    	.MessageBox dd 0
    	
    Strings:
    	.u32 db 'user32.dll',0
    	.MessageBoxA db 'MessageBoxA',0
    	.LoadLibraryExA db 'LoadLibraryExA',0
    	.cap db 'Caption',0
    	.msg db 'No IATs needed!',0
    	
    main:
    	call GetKERNELBASE
    	mov [k32],eax
    	
    	push Strings.LoadLibraryExA
    	push dword [k32]
    	call MyGetProcAddress
    	cmp eax,0
    	je .break
    	mov [k32.LoadLibraryEx],eax
    	
    	push 0
    	push 0
    	push Strings.u32
    	call [k32.LoadLibraryEx]
    	mov [u32],eax
    	
    	push Strings.MessageBoxA
    	push dword [u32]
    	call MyGetProcAddress
    	mov [u32.MessageBox],eax
    	
    	push 0
    	push Strings.cap
    	push Strings.msg
    	push 0
    	call [u32.MessageBox]
    	.break: ;Couldn't find LoadLibraryExA
    	ret
    	
    
    GetKERNELBASE:
    	mov eax,[fs:0x30]
    	mov eax,[eax+0x0c]
    	mov eax,[eax+0x1c]
    	mov eax,[eax]
    	mov eax,[eax+0x08]
    	ret
    
    MyGetProcAddress:
    	push ebp
    	mov ebp,esp
    	push ebx
    	push ecx
    	push esi
    	push edi
    	mov dword eax,[ebp+8]
    	mov [.modb],eax ;Get module base address
    	mov dword eax,[ebp+12] ;String to cmp
    	mov [.fname],eax
    	mov eax,[.modb]
    	add eax,60
    	mov eax,[eax] ;get e_lfanew
    	add eax,[.modb] ;PE Header
    	add eax,0x78 ;now points to export directory address
    	mov eax,[eax] ;... and get that address
    	add eax,[.modb]
    	mov [.ied],eax
    	mov ebx,[eax+24] ;get the number of names
    	mov [.non],ebx
    	mov ebx,[eax+28] ;get the addresses of functions
    	mov [.aof],ebx
    	mov ebx,[eax+32] ;get the addresses of names
    	mov [.aon],ebx
    	mov ebx,[eax+36] ;get the addresses of name ordinals
    	mov [.aono],ebx
    
    	xor ecx,ecx
    	.loop:
    	mov dword esi,[.fname]
    	cmp dword ecx,[.non]
    	jnl .break
    	mov dword ebx,[.aon]
    	add dword ebx,[.modb]
    	mov eax,4
    	mul ecx
    	add ebx,eax
    	mov dword ebx,[ebx]
    	add ebx,[.modb]
    	mov edi,ebx
    	.chkstr:
    	cmpsb
    	jne .continue
    	cmp byte [esi-1],0
    	jne .chkstr
    	cmp byte [edi-1],0 ;checking edi isn't necessary, but it's here for safety anyway
    	jne .chkstr
    	mov dword ebx,[.aono]
    	add dword ebx,[.modb]
    	mov eax,2
    	mul ecx
    	add ebx,eax
    	mov word bx,[ebx]
    	mov [.ordinal],bx
    	mov ebx,[.aof]
    	add dword ebx,[.modb]
    	mov eax,4
    	mul [.ordinal]
    	add ebx,eax
    	mov eax,[ebx]
    	add eax,[.modb]
    	pop edi
    	pop esi
    	pop ecx
    	pop ebx
    	mov esp,ebp
    	pop ebp
    	ret 8
    	.continue:
    	inc ecx
    	jmp .loop
    	.break:
    	popa
    	mov esp,ebp
    	pop ebp
    	ret 8
    
    	.modb dd 0
    	.ordinal dw 0
    	.fname dd 0
    	.ied dd 0
    	.non dd 0
    	.aon dd 0
    	.aono dd 0
    	.aof dd 0


    Maybe your a C programmer, so here's some C code to do it (made by someone else based on my findings). However, some imports were used which can easily be replaced with lower-level C code -or- if your compiler supports in-line assembly, you can just use the above.
     

    Get the KERNELBASE address.
    Code:
    void __declspec(naked) *GetKERNELBASE() {
        __asm {
            mov eax, fs:[0x30]
            mov eax, [eax+0x0c]
            mov eax, [eax+0x1c]
            mov eax, [eax]
            mov eax, [eax+0x08]
            ret
        }
    }
    Your GetProcAddress function.
    Code:
    void *MyGetProcAddress(HMODULE modl, char *fname) {
        unsigned long modb          = (unsigned long)modl;
        IMAGE_DOS_HEADER *dosh      = (IMAGE_DOS_HEADER *)modb;
        IMAGE_NT_HEADERS *nth       = (IMAGE_NT_HEADERS *)(modb+dosh->e_lfanew);
        IMAGE_EXPORT_DIRECTORY *ied = (IMAGE_EXPORT_DIRECTORY *)(modb+nth->OptionalHeader.DataDirectory->VirtualAddress);
        unsigned int i;
     
        for(i = 0; i < ied->NumberOfNames; i++) {
            const char *nn = (*(const char **)(ied->AddressOfNames+modb+i*sizeof(void *)))+modb;
     
            if(!strcmp(fname, nn)) { //You can replace strcmp with your own string compare
                unsigned short ordinal = *(unsigned short *)(ied->AddressOfNameOrdinals+modb+i*sizeof(unsigned short));
                return (void *)((unsigned long)*(void **)(ied->AddressOfFunctions+modb+ordinal*sizeof(void *))+modb);
            }
        }
     
        return NULL;
    }
    Get LoadLibraryEx's address
    Code:
    HMODULE (__stdcall *dyn_ll)(LPCTSTR lpFileName,HANDLE hFile,DWORD dwFlags);
    dyn_ll = MyGetProcAddress(kern, "LoadLibraryExA");
    Of course, you may want to load a lot of library functions. So you can do something like this:
    Code:
    char *func_kernel[] = {
        "AllocConsole", // 0
        "GetStdHandle", // 1
        "WriteConsoleA", // 2
    };
    unsigned long (__stdcall *k32[sizeof(func_kernel)/sizeof(*func_kernel)])();
    
    char *func_user[] = {
        "MessageBoxA", // 0
        "GetWindowTextA", // 1
    }
    unsigned long (__stdcall *u32[sizeof(func_user)/sizeof(*func_user)])();
    
    HMODULE (__stdcall *my_ll)(LPCTSTR lpFileName,HANDLE hFile,DWORD dwFlags);
    
    void load_imports() {
        HMODULE kern,user,kern32;
        unsigned long i;
     
        kern   = GetKERNELBASE();
        my_ll = MyGetProcAddress(kern, "LoadLibraryExA");
        kern32 = my_ll("kernel32.dll");
        user   = my_ll("user32.dll");
     
        for(i = 0; i < sizeof(func_kernel)/sizeof(*func_kernel); i++)
            k32[i] = MyGetProcAddress(kern32, func_kernel[i]);
     
        for(i = 0; i < sizeof(func_user)/sizeof(*func_user); i++)
            u32[i] = MyGetProcAddress(user, func_user[i]);
    }
    
    int main(int argc, char *argv[]) {
        load_imports();
        u32[0](0, "No IATs created!", "Caption", 0);
        return EXIT_SUCCESS;
    }
    Have fun with it...


    After all that you may be like:
    Quote Originally Posted by Idiot
    Why is this useful omg theres not point arrow me to its not useful.
    or maybe
    Quote Originally Posted by Intelligent
    Good post, but how can this be used?
    Well, some "anti-hacks" work off the import table. Therefore, without an import table for it to go off of, you can create undetected hacks. Furthermore, you can encrypt the strings to make your hack 100% free of "*.dll" strings.

    Have fun with it...

  2. #2
    Immortalhf's Avatar
    Join Date
    Apr 2013
    Gender
    male
    Posts
    1
    Reputation
    10
    Thanks
    0
    Wow thanks alot this just gave me an idea. On running a file from memory fully undetected Thank you.

Similar Threads

  1. Any upcoming Releases for Hacks?
    By shelbyma in forum War of Roses Hacks & Cheats
    Replies: 2
    Last Post: 10-17-2012, 07:23 PM
  2. account giveaway (good for hack testing) and some 1500 bp
    By PasterOfMuppets in forum CrossFire Discussions
    Replies: 7
    Last Post: 05-19-2012, 07:08 AM
  3. [Release] Make Combat Arms windowed [without any downloadings]
    By ♪ςander!♪ in forum Combat Arms Tutorials
    Replies: 19
    Last Post: 07-16-2011, 12:56 PM
  4. Very Good Clan without Any hack
    By master1555 in forum General Gaming
    Replies: 2
    Last Post: 07-07-2010, 06:21 AM
  5. Any good working hacks for windows xp pro?
    By bigbelow in forum Call of Duty Modern Warfare 2 Help
    Replies: 4
    Last Post: 04-16-2010, 06:56 AM