flat assembler
Message board for the users of flat assembler.

Index > Windows > access API when using format binary

Author
Thread Post new topic Reply to topic
xoru



Joined: 02 Dec 2013
Posts: 9
Location: Netherlands
xoru 02 Dec 2013, 20:42
Hi there,

I've been using fASM for a while, and in certain projects with dynamic scripting languages I'm implementing blocks of assembly code to also enable some sort of inline-assembly (after calling a function to assemble the code).

Now, these blocks of code are assembled using the binary format ('format binary'). Is there any way to access Windows API functions from those chunks without pushing pointers to functions on the stack before I execute the block?

format binary has no sections, so I'm curious what I could do.


Also, I'm new to the community, so I'm hoping to learn a lot!

Cheers,
Bas

_________________
HLT
Post 02 Dec 2013, 20:42
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20445
Location: In your JS exploiting you and your system
revolution 02 Dec 2013, 20:49
You're going to find trouble if you really want to do API function binding the "hard way". You need to scan the memory space looking for DLL signatures and then try to find the function you want within the DLL. It is tricky because you have to be careful when generating an exception by reading unallocated memory areas. Also, different versions of the OS put things in different places so even finding a reliable starting point is problematic.

In short: It can be done, but it requires much more more effort than necessary.
Post 02 Dec 2013, 20:49
View user's profile Send private message Visit poster's website Reply with quote
xoru



Joined: 02 Dec 2013
Posts: 9
Location: Netherlands
xoru 02 Dec 2013, 20:53
I understand, so would you suggest I push a LoadLibrary and GetProcAddress to the binary chunks?
Post 02 Dec 2013, 20:53
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20445
Location: In your JS exploiting you and your system
revolution 02 Dec 2013, 20:58
xoru wrote:
I understand, so would you suggest I push a LoadLibrary and GetProcAddress to the binary chunks?
It only takes a minute or two to code up. And about the same time to debug.

Compare that to how much time you would likely spend coding up and debugging a memory scanning, exception handling, export searching piece of code.
Post 02 Dec 2013, 20:58
View user's profile Send private message Visit poster's website Reply with quote
xoru



Joined: 02 Dec 2013
Posts: 9
Location: Netherlands
xoru 02 Dec 2013, 21:03
revolution wrote:
xoru wrote:
I understand, so would you suggest I push a LoadLibrary and GetProcAddress to the binary chunks?
It only takes a minute or two to code up. And about the same time to debug.

Compare that to how much time you would likely spend coding up and debugging a memory scanning, exception handling, export searching piece of code.


Good point, I think I was merely hoping for some magical solution that was already known to someone who came across this problem. I'll go with the easy solution, thanks for your input! Smile

_________________
HLT
Post 02 Dec 2013, 21:03
View user's profile Send private message Visit poster's website Reply with quote
xoru



Joined: 02 Dec 2013
Posts: 9
Location: Netherlands
xoru 02 Dec 2013, 23:54
Now, I don't want to go off-topic too much, however when I keep assembling binary chunks, I would love a practical method to access the correct address to labels defined in these chunks. Currently I'm using the next macro users can call to initialize a chunk and determine the absolute base address for this code;

Code:
macro init32 {
        USE32
        call _init32_findBase
        _init32_findBase: 
                pop eax
                sub eax, ($ - 1)
        
        push    ebp
        mov     ebp, esp
        sub     esp, 4
        mov     [ebp - 4], eax
        
        data_base equ [ebp - 4]
}    


- However, this is not available in e.g. a proc, only in labels and the main code. What is a more proper way to determine the base address and resolve label addresses everywhere in the code?

_________________
HLT
Post 02 Dec 2013, 23:54
View user's profile Send private message Visit poster's website Reply with quote
xoru



Joined: 02 Dec 2013
Posts: 9
Location: Netherlands
xoru 04 Dec 2013, 15:02
Even though the simple solution seemed wise, I forgot that the small assembled chunks should be executed from external processes as well (as callback functions). In those situations, I cannot rely on pushing function addresses to the chunk.

I looked around on the web a lot, and found some code on these forums; http://board.flatassembler.net/topic.php?p=103427#103427

And some code elsewhere which resulted in me making two procs to search for GetProcAddress. I'm sure it's not the best solution out there, but it gets me where I wanna be.

Code:
proc findk32
    PUSH    ESI EDI
    
    XOR     ECX, ECX                    ; ECX = 0     
    MOV     ESI, [FS:ECX + 0x30]        ; ESI = &(PEB) ([FS:0x30])     
    MOV     ESI, [ESI + 0x0C]           ; ESI = PEB->Ldr     
    MOV     ESI, [ESI + 0x1C]           ; ESI = PEB->Ldr.InInitOrder 
    
    next_module:     
        MOV     EAX, [ESI + 0x08]           ; EBP = InInitOrder[X].base_address     
        MOV     EDI, [ESI + 0x20]           ; EBP = InInitOrder[X].module_name (unicode)     
        MOV     ESI, [ESI]                  ; ESI = InInitOrder[X].flink (next module)     
        
        ; check if first char is 'k'
        MOV     CX, 'k'
        CMP     [EDI], CX                   ; modulename[0] == 'k' ?
        JNE     next_module
        
        ; check if second char is 'e'
        MOV     CX, 'e'
        CMP     [EDI + 2], CX               ; modulename[1] == 'e' ?
        JNE     next_module
        
        ; find null char at correct location (kernel32.dll\0)
        XOR     ECX, ECX
        CMP     [EDI + 12*2], CX            ; modulename[12] == 0 ?     
        JNE     next_module                 ; No: try next module.
    
    POP     EDI ESI
    ret
endp

proc findgpa base_address
    PUSH    EBP ESI EDI
    
    MOV     ESI, [base_address]
    
    MOV     EBX, [ESI + 3ch]                ; offset to PE, MZ + 3ch
    MOV     EAX, [ESI + EBX + 78h]          ; export table
    
    MOV     ECX, [ESI + EAX + 4 * 6]        ; number of names
    MOV     EDI, [ESI + EAX + 4 * 7]        ; address table
    MOV     EBX, [ESI + EAX + 4 * 8]        ; name ptr table
    MOV     EBP, [ESI + EAX + 4 * 9]        ; Ordinal table
    MOV     EDX, EBX                        ; EDX = name ptr table
    
    findgpa_nex1:
        MOV     EAX, [ESI + EBX]            ; Get name pointer and search
        
        CMP     DWORD [ESI + EAX], 'GetP'   ; for GetProcAddress in name ptr table
        JE      findgpa_found_getP
        ADD     EBX, 4                      ; try again           
    loop findgpa_nex1
    JMP findgpa_return                      ; give up
    
    findgpa_found_getP:
        CMP     DWORD [ESI + EAX + 4], 'rocA'
        JE      findgpa_found_rocA
        ADD     EBX, 4
        JMP     findgpa_nex1
        
    findgpa_found_rocA:
        CMP     DWORD [ESI + EAX + 8], 'ddre'
        JE      findgpa_found_ddre
        ADD     EBX, 4
        JMP     findgpa_nex1
        
    findgpa_found_ddre:
        SUB     EBX, EDX                    ; Name ptr table offset to GetProcAddress
        SHR     EBX, 1                      ; Ordinals are 'words', adjust for ordinals
        ADD     EBP, ESI
        MOVZX   EBX, WORD [EBP + EBX]       ; Ordinal table offset
        
        SHL     EBX, 2                      ; Back to dword steps
        
        ADD     EBX, EDI                    ; Position in address table worked out from ordinal table
        MOV     EDI, [ESI + EBX]            ; RVA
        ADD     EDI, ESI                    ; EDI = GetProcAddress function
        
        ; ESI = HMODULE to kernel32.dll
        ; EDI = GetProcAddress@8
        MOV     EDX, ESI
        MOV     EAX, EDI
        
    findgpa_return:
    POP     EDI ESI EBP
    ret
endp    


Also; I'd love to have some opinions regarding my previous post, so let's call this a bump post as well

Cheers!

_________________
HLT
Post 04 Dec 2013, 15:02
View user's profile Send private message Visit poster's website Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2909
Location: 0x77760000
typedef 05 Dec 2013, 07:34
xoru wrote:
Hi there,

I've been using fASM for a while, and in certain projects with dynamic scripting languages I'm implementing blocks of assembly code to also enable some sort of inline-assembly (after calling a function to assemble the code).

Now, these blocks of code are assembled using the binary format ('format binary'). Is there any way to access Windows API functions from those chunks without pushing pointers to functions on the stack before I execute the block?

format binary has no sections, so I'm curious what I could do.


Also, I'm new to the community, so I'm hoping to learn a lot!

Cheers,
Bas


Are you making injectors (injecting self-aware code) or some sort of framework?

If it's a framework you can simply add headers to your binary indicating which library the binary depends on and where the addresses to the functions should be put (in the binary). Possibilities are endless. You can even save yourself some time and make a reference table where each windows DLL has an index. The index will be used in the binary instead of the actual name of the DLL.

Code:
format binary as "ext"

; structure representing API dependency
; struct
;{
;  DWORD dwDepends; number of DLLS
;  DWORD dwEntryPoint; pointer to block of executable code
;}

; struct {
;    WORD wIndex;   If index < 0, then loading custom DLL
;    DWORD  dwAddress; pointer to address to be filled with appropriate function address 
;    DWORD  pszDLL; pointer to chars containing dll name to load (can be at the end of code)
;    DWORD  pszFunction; pointer to name of function in referenced DLL.
; }

; header
; number of DLLs
dd 2
dd entry_point


; first dll referenced
dw     0   ;   (user32.dll) See table below
dd     fnMsgBox
dd     0  ; not needed. Used table
dd     pszMsgBox

; 2nd dll referenced (Custom, or can also be added to table. You decide)
dw     -1   ;
dd     fnAdd
dd     pszCustomDLL
dd     pszAdd

;; pointers
fnMsgBox dd 0
fnAdd       dd 0

;; code
entry_point:

push   0
push   0
push   0
push   0
call     dword[fnMsgBox]

; add 3+2
push 3
push 2
call   dword[fnAdd]

; ... more code

; data
pszMsgBox db 'MessageBoxW',0
pszAdd       db 'Add',0
pszCustomDLL db 'customlib.dll',0


    


And the table in your interpreter could be something like.

Code:
dd dwUser32; ;Index = 0
dd dwKernel32;
...
dwUser32   db 'user32.dll',0
dwKernel32 db 'kernel32.dll',0
    


Your interpreter loads the binary, parses the headers and loads and maps appropriate DLL functions then passes control to your binary code under an exception handler of course.
Post 05 Dec 2013, 07:34
View user's profile Send private message Reply with quote
xoru



Joined: 02 Dec 2013
Posts: 9
Location: Netherlands
xoru 05 Dec 2013, 11:47
Hi typedef,

Thanks for your reply.

I'm doing neither, my implementation of fASM in my project is allowing Lua coders in AutoPlay Media Studio to assemble functions they can use in interaction with application programming interfaces with Windows, Libraries (such as cURL) etc.

Lua functions are functions in the LuaVM, not blocks of machine instructions, so these cannot be called as (e.g.) a window subclass function. These binary chunks allow the programmer to have this possibility.

Another reason for why I'm using the binary fASM format, is so that the programmer can implement (e.g.) a fast and small CRC32 (or any other) algorithm in their Lua projects, without having a DLL or Lua module as dependency.

I'm building a set of includes for the assembler that will allow the programmer to interface with Windows API easily so that they can also call external functions from within their code.

Anyhow, that is pretty much why I'm doing all this. The last step for me is to figure out how to determine the absolute addresses to data labels with easy for the programmer. I know how to determine the base address of the code (it's never a fixed address, VirtualAlloc(Null, ....)) and from that, determine the absolute address of the label. I'm probably missing a beautiful feature of fASM which will allow me to do that more easily, but I'm not sure which one!

Cheers,
Bas

_________________
HLT
Post 05 Dec 2013, 11:47
View user's profile Send private message Visit poster's website Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 05 Dec 2013, 14:36
xoru,

Have you seen alien module? It allows DLL functions to be called from Lua almost directly.

Compile-and-run approach can be implemented as custom FASM.DLL build (with proper Lua bindings) which recognizes special symbols like Kernel32.DLL!GetCommandLineA as a references to external addresses and properly snaps them before execution. Arguments conversion is still non-trivial task (that's why I recommend alien).
Post 05 Dec 2013, 14:36
View user's profile Send private message Reply with quote
xoru



Joined: 02 Dec 2013
Posts: 9
Location: Netherlands
xoru 05 Dec 2013, 14:51
baldr wrote:
xoru,

Have you seen alien module? It allows DLL functions to be called from Lua almost directly.

Compile-and-run approach can be implemented as custom FASM.DLL build (with proper Lua bindings) which recognizes special symbols like Kernel32.DLL!GetCommandLineA as a references to external addresses and properly snaps them before execution. Arguments conversion is still non-trivial task (that's why I recommend alien).


Hi there baldr,

I have heard from Alien, also my own module (specific to AutoPlay Media Studio) does also allow for calling DLL functions as if they were native Lua functions (http://www.memoryex.net/mx.html) and catches calling convention automatically, this is not my problem.

My problem is that some systems (in DLL's, modules or WinAPI) require a callback function. Lua functions can't do the trick in that case, so real-time assembly is the solution I have chosen so that a Lua scripter can also create callback functions for these systems.

I also chose for real-time assembly (or when using the package IMXLH in combination with MemoryEx; pre-assembled code inside compiled Lua files) to enable a programmer to implement fast algorithms and data processing routines without having to include an external module, DLL or library just for that reason.

This real-time assembly is already implemented and used, however by implementing more macro-ic features I am trying to make it easier for more people to write fASM code that can help them out in their AMS Lua project. My only set-back now is relative / absolute label addresses when accessing data inside the assembly.

_________________
HLT
Post 05 Dec 2013, 14:51
View user's profile Send private message Visit poster's website 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-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.