flat assembler
Message board for the users of flat assembler.
Index
> Windows > 'Import' proc. |
Author |
|
velox 18 Jun 2006, 09:57
hi,
i'm using this snippet for finding api addresses: Code: init_apis: mov esi,first_dll mov edi,esi imp_loop: lodsd cmp dword [eax],0 ; reached end? jz imp_fin cmp byte [eax],0xFF ; is dll? jz @F jmp getaddr @@: inc eax invoke LoadLibrary,eax mov ebx,eax stosd jmp imp_loop getaddr: invoke GetProcAddress,ebx,eax stosd jmp imp_loop imp_fin: dll1 db 0xFF,'1.DLL',0 api1 db 'func1',0 api2 db 'func2',0 api3 db 'func3',0 dll2 db 0xFF,'2.DLL',0 api4 db 'func4',0 endm dd 0 first_dll: _hdll1 dd dll1 _func1 dd api1 _func2 dd api2 _func3 dd api3 _hdll2 dd dll2 _func4 dd api4 _endmark dd endm |
|||
18 Jun 2006, 09:57 |
|
okasvi 18 Jun 2006, 10:08
Really nice, never thought of prefixing DLL, btw. you dont need '.DLL' ending
I just realised that I had few extra instructions left in my proc. Edited it. edit: hmm... I thought of using ebx for module handle of library too but my procs cant touch ebx as my calls are really [ebx+SOMESTRUCTURE.Api] so decided to use stack. |
|||
18 Jun 2006, 10:08 |
|
dreamhack 03 Jul 2006, 09:37
Last edited by dreamhack on 16 Jul 2006, 21:59; edited 1 time in total |
|||
03 Jul 2006, 09:37 |
|
Reverend 06 Jul 2006, 09:25
Here is the smallest code for getting GetProcAddress address
Code: ; noimport.asm (c) Northfox, rambo, Reverend ; 52 bytes. use32 start: pop ecx push ecx @@: cmp word [ecx - 1], 'MZ' loopnz @b mov ebp, ecx add ecx, dword [ecx+60] mov eax, dword [ecx+120] mov esi, dword [ebp+eax+28] add esi, ebp mov eax, dword [ebp+eax+32] mov edi, dword [ebp+eax] add edi, ebp @@: salc .1: cmp word [edi], 'cA' jz @f scasb jnz .1 lodsd jmp @b @@: lodsd add eax, ebp ; eax - GetProcAddress ; ebp - kernel32.dll ret |
|||
06 Jul 2006, 09:25 |
|
f0dder 06 Jul 2006, 09:32
Whoa that looks like safe code, Reverend... but I guess it's useful if you're into shellcode >_<
|
|||
06 Jul 2006, 09:32 |
|
Reverend 06 Jul 2006, 20:16
The code was heavily tested. I know it may look weird, as instead of PE specific structures there are just constants, but everything works.
Or maybe I misunderstood sth? What did you mean by saying "if you're into shellcode"? |
|||
06 Jul 2006, 20:16 |
|
f0dder 06 Jul 2006, 20:45
Well, one thing is that you're not using PE structures - for my PE protector level1 stub loader I chose to use direct offsets as well (but with comments) - no need to set up structures for stuff that's only used once.
What I mean is that you're only testing for 'cA', which COULD give a false positive some day... and you're not taking into account that GetProcAddress could be forwarded (granted, I've never seen this on an actual system, but if it happens you're screwed majorly). So well, this code is fine if you're doing 4k intros or shellcode, but I hope nobody would use it for "production" programs. |
|||
06 Jul 2006, 20:45 |
|
vid 06 Jul 2006, 21:06
f0dder: knowledge itself can't be restricted because it can be misused. then all the assembly should be banned
|
|||
06 Jul 2006, 21:06 |
|
f0dder 06 Jul 2006, 21:08
vid wrote: f0dder: knowledge itself can't be restricted because it can be misused. then all the assembly should be banned Not saying it should, just saying you should know WHEN to use this kind of code... and especially WHEN NOT _________________ - carpe noctem |
|||
06 Jul 2006, 21:08 |
|
Reverend 07 Jul 2006, 19:54
f0dder: Now I see what you mean. So let me explain. The code I pasted was originally created by Northfox - the creator of MEW exe packer (also the constants instead of PE structures). Rambo and I optimized it.
The trick with 'cA' worked in all tests I made, but of course it's not a perfect solution for all variants. The forwarding of GetProcAddress is rather impossible. But you are right that a 100% correct loader should take it into account. But remember, that it was done to be the SMALLEST possible solution. And it's a feature of all most optimized solutions that they work in specific opportunities. It's not a code working in every circumstances BTW. Is your PE Protector public? I'm interested in the subjects of packers/protectors |
|||
07 Jul 2006, 19:54 |
|
dreamhack 07 Jul 2006, 22:55
that northfox's code is something like using:
mov eax,[esp] and eax,$FFFF0000 add eax,$1000 @@: sub eax,$1000 cmp dword[eax],$00905A4D jnz @b to get kernel32 'handle' or xor esp,esp to exit the program by the way, northfox's mew packer rulez |
|||
07 Jul 2006, 22:55 |
|
RedGhost 08 Jul 2006, 01:29
i use this to hide my imports from anti-cheat clients and etc, works for ordinal/name like GetProcAddress and finds the correct addresses for mixed export tables (had a problem with some winsock lib iirc), also it uses no imports itself allowing for 0 imports on XP, the win2000 loader requires one valid import though
(sorry i wrote it in C) Code: unsigned long __stdcall GetProcedureAddress( unsigned long module_base, char *procedure_name ) { if( module_base == 0 || (unsigned short *)procedure_name == 0 ) { return 0; } IMAGE_DOS_HEADER *idh; IMAGE_NT_HEADERS *inth; IMAGE_EXPORT_DIRECTORY *ied; unsigned long *export_addresses_table; unsigned short *export_ordinals_table; idh = (IMAGE_DOS_HEADER *)module_base; if( idh->e_magic != IMAGE_DOS_SIGNATURE ) { return 0; } inth = (IMAGE_NT_HEADERS *)( module_base+idh->e_lfanew ); if( inth->Signature != IMAGE_NT_SIGNATURE ) { return 0; } ied = (IMAGE_EXPORT_DIRECTORY *)( module_base+inth->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ].VirtualAddress ); export_ordinals_table = (unsigned short *)( module_base+ied->AddressOfNameOrdinals ); export_addresses_table = (unsigned long *)( module_base+ied->AddressOfFunctions ); if( (unsigned short)( (unsigned long)procedure_name >> 16 ) == 0 ) { goto _ordinal; } unsigned long *export_names_table = (unsigned long *)( module_base+ied->AddressOfNames ); for( short i = 0; i < ied->NumberOfNames; i++ ) { if( strcmp( (char *)( export_names_table[ i ]+module_base ), procedure_name ) == 0 ) { //use ordinal not loop counter to get proper address on mixed export tables return (unsigned long)( module_base+export_addresses_table[ (unsigned short)( module_base+export_ordinals_table[ i ] ) ] ); } } return 0; _ordinal: for( short i = 0; i < ied->NumberOfFunctions; i++ ) { if( (unsigned short)( export_ordinals_table[ i ]+module_base ) == (unsigned short)( (unsigned long)procedure_name & 0xFFFF ) ) { return (unsigned long)( module_base+export_addresses_table[ (unsigned short)( module_base+export_ordinals_table[ i-1 ] ) ] ); } } return 0; } //--- _________________ redghost.ca |
|||
08 Jul 2006, 01:29 |
|
f0dder 08 Jul 2006, 11:36
Reverend wrote:
No, sorry - and the sources are currently in a state where I don't even know if it'll compile :/ - haven't worked on it for ~4 years or so. _________________ - carpe noctem |
|||
08 Jul 2006, 11:36 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.