flat assembler
Message board for the users of flat assembler.

Index > Windows > calling win32 APIs without imports!

Author
Thread Post new topic Reply to topic
shakuni



Joined: 11 Oct 2007
Posts: 24
shakuni 16 Oct 2007, 13:01
I found this code a few months back while browsing through the examples that come with the masm32 package.I could not understand it then so I forgot it.Now while I was researching my win32 codes for translating them to fasm I came across this again-
Code:
; =======================================
; NO_IMPORT by mob aka drcmda
; this program demonstrates how to write
; portable code... this code could be
; added to other executables with no prob.
; i'm over that virus shit so don't waste
; your time... i'm working on something
; like a executable patcher right now so
; portable code was very interesting for
; me...................................
; if you want to use other apis or other
; dll's then use this structure:
;
; 00      db ?? ;lenght of name
; 01 - ?? db ?? ;API name
; ??      dd ?? ;pointer
;
; then use 'GetApis' to find their
; pointers so you don't have to search
; the pointers with GetModuleHandle
; write to drcmda@gmx.de 
; =======================================

; ---------------------------------------------------
; Build with MAKEIT.BAT to merge the .text and .data
; sections. Result is a 1024 byte length EXE file.
; ---------------------------------------------------

.486
.Model      Flat, Stdcall
Option      Casemap:None

.Data

; kernel32.dll api's
___Kernel32         db 14,"GetProcAddress"
_Getprocaddress     dd 0
                    db 11,"LoadLibrary"
_Loadlibrary        dd 0
                    db 11,"ExitProcess"
_Exitprocess        dd 0

; user32.dll api's
___User32           db 11,"MessageBeep"
_Messagebeep        dd 0
                    db 10,"MessageBox"
_MessageBox         dd 0                    

_Kernel             Dd 0
_User32             db "USER32",0
_Default            Dd 0   

.Code       
    
Start:
            Call    Delta
Delta:
            Pop     Ebp                                 ; get deltaofs    
            Sub     Ebp,Offset Delta                    ; for portability         
            
            Call    Get_Kernel                          ; get kernel base/set default
            
            Push    3                                   ; 3 api's in the kernel32 struc
            pop     Ecx
            Lea     Esi,[Ebp+Offset ___Kernel32]                                           
            Call    Get_Apis                            ; get kernel apis
                       
            Lea     Eax,[Ebp+Offset _User32]            ; load user32.dll
            Push    Eax
            Call    [Ebp+_Loadlibrary]            
            
            test    Eax,Eax
            jz      Error_Exit

            Mov     [Ebp+Offset _Default],Eax           ; store result in 'default'

            push    2                                   ; 4 api's in the user32 struc
            pop     Ecx
            Lea     Esi, [Ebp+Offset ___User32]                                           
            Call    Get_Apis                            ; get user32 apis           
                                  
            Push    -1
            Call    [Ebp+_Messagebeep]                  ; beep
            
            Push    0
            Call    _t02
            db      "little test",0
_t02:       Call    _t01
            db      "MessageBox without imports, funny eh?",0
_t01:       Push    0
            Call    [Ebp+_MessageBox]                   ; messagebox

Error_Exit:                                
            Push    0
            Call    [Ebp+_Exitprocess]                  ; get out


; ######################## get kernel ########################
; returns kernelbase and stores it in 'default' and 'kernel'
Get_Kernel:
            Mov     Ecx,[Esp+4] ; get kerneladdr from stack
            
Kernel_Loop:
            Xor     Edx,Edx
            Dec     Ecx
            Mov     Dx,[Ecx+3Ch] 
            Test    Dx,0F800H
            Jnz     Kernel_Loop
            Cmp     Ecx,[Ecx+Edx+34H]
            Jnz     Kernel_Loop            
            Mov     [Ebp+Offset _Kernel],Ecx
            Mov     [Ebp+Offset _Default],Ecx                                             
            Ret

; ######################## get apis   ########################
; default   = dll base
; ecx       = number of api's in the structure
; esi       = pointer to structure
Get_Apis:  
            Xor     Ebx,Ebx
Api_Loop:
            Inc     Esi         ; scan through the api
            Push    Ecx         ; table and try to
            Movzx   ecx, byte ptr [Esi-1] ; addresses...                
            Push    Ecx
            Call    Get_Api
            Pop     Ebx
            Pop     Ecx
            Add     Esi,Ebx            
            Mov     [Esi],Eax
            Add     Esi,4
            Loop    Api_Loop
            Ret       

; ######################## get api    ########################
; default = dll base
; ecx     = structure entry
Get_Api:   
            Mov     Edx, [Ebp+Offset _Default]
            Add     Edx, [Edx+3Ch] ; get default module        
            Mov     Edx, [Edx+78H]
            Add     Edx, [Ebp+Offset _Default]

            Mov     Edi, [Edx+32] ;Get Addrofnames
            Add     Edi, [Ebp+Offset _Default]
            Mov     Edi, [Edi] ;Get Addrofnames
            Add     Edi, [Ebp+Offset _Default]
            Mov     Eax, [Edx+24] ;Get Numberofnames                                   
            Xor     Ebx,Ebx
Next_One:            
            Push    Ecx
            Inc     Ebx          
            Push    Esi
            Push    Edi
            Repz    Cmpsb ; compare api with export
            Pop     Edi
            Pop     Esi
            Jnz     Not_Found            
            Pop     Ecx
            Mov     Ecx, [Edx+36] ;Get Addrnameord
            Add     Ecx, [Ebp+Offset _Default]
            Dec     Ebx
            Movzx   eax, word ptr [Ecx+Ebx*2]                        
            Mov     Ebx, [Edx+28] ;Get Addroffunctions
            Add     Ebx, [Ebp+Offset _Default]
            Mov     Eax, [Ebx+Eax*4]                
            Add     Eax, [Ebp+Offset _Default]
            Ret
Not_Found:  
            Dec     Edi            
Loop_1:
            Inc     Edi
            Cmp     Byte Ptr [Edi],0
            Jnz     Loop_1

            Inc     Edi            
            Dec     Eax
            Jz      Exit_Search            
            Pop     Ecx
            Jmp     Next_One
Exit_Search:  
            Jmp     Error_Exit
            Ret                        
        
End         Start
    


The problem is that i have some problems understanding it.Although I know about the PE file structure and this program is just getting the handle for the api from the dll handling that api.But still there is some consusion.
can somebody please give some hint???
Post 16 Oct 2007, 13:01
View user's profile Send private message Reply with quote
FrozenKnight



Joined: 24 Jun 2005
Posts: 128
FrozenKnight 16 Oct 2007, 20:12
What this program appears to do is get the kernel address from the programs return on the stack. Then manually walk through the kernel to find the address of the kernel api loader.

of course this is all conjecture.
Post 16 Oct 2007, 20:12
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< 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-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.