I found this code while browsing through the examples that come with the masm32 package.
; =======================================
; 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 [email protected]
; =======================================
; ---------------------------------------------------
; 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.
Hey i've the same problem too... i had some trouble finding where i could import additional dlls...
mob wrote this piece of code some years ago and at the time it was a technique used to make an executable file harder to hack as you could not routinely set Softice to a breakpoint of a simple API like GetWindowText() and get it to stop when the API was being executed. Apart from an anti-hacking technique it is not much use apart from the virus brigade trying to stealth a section of code that calls various API functions by their address rather than by a name in the import table.
If we catch any of this nonsense in here it will get the hatchet like Haley's comet.
I guess Windows 2000 will refuse silently to run the application because W2K expects at least one imported function from kernel32.dll
correct, same with xp i think and most likely vista...
making an importless executable is rather uncommon, and used for spyware/malware/rootkits/code injection
@shakuni and john9811 - what exactly is it you're trying to achieve?
QuoteI guess Windows 2000 will refuse silently to run the application because W2K expects at least one imported function from kernel32.dll
Quotesame with xp i think and most likely vista
I don't know about 2k but it works under XP and vista.
Quotewhat exactly is it you're trying to achieve?
Trying to learn "everything" about assembly language.
Trying to do what some people consider to be impossible.
Quote from: shakuni on October 18, 2007, 09:19:46 AM
Trying to learn "everything" about assembly language.
Trying to do what some people consider to be impossible.
The questionable part of this has nothing directly to do with assembly language.
Quote from: shakuni on October 18, 2007, 09:19:46 AM
Trying to do what some people consider to be impossible.
hows it impossible if someone has already shown its possible?
and hmm you're right it does work in xp.. just tested.. patch some exe with imports to have none (wipe data directories in pe header), and put an int 3 at the entrypoint.. it got there... odd
QuoteThe questionable part of this has nothing directly to do with assembly language.
Yes Sir,it has nothing to do with "assembly language". But it is certainly related to application of assembly language.
Quotehows it impossible if someone has already shown its possible?
Yes Sir,it has been done already.But when I say that I am trying to do impossible things with assembly language, those are some other things that come to my mind while studying.The problems I ask, like the one above, is only a mean to that end.I would very soon post about those impossible things.
QuoteBut when I say that I am trying to do impossible things with assembly language
If something is feasible, it means that it's not impossible to do :)
yes you're right, but "some people" consider it impossible.
Yes, win2000 expects at least one imported function from kernel32.dll. But Microsoft removes this rule on XP and Vista, may be on win2000+sp4 this code will work.
I don't remember correctly. Only some Sp's require IAT
About this method.
This is old known method, by getting address of kernel32.dll from stack. Many commercial protectors and packers (like Asprotect and others) use this method.
For executing executables Windows uses CreateProcess function. In internals of this function has code:
7C816FB4 _BaseProcessStart@4:
7C816FB4 push 0Ch
7C816FB6 push offset stru_7C816FE0
7C816FBB call __SEH_prolog
7C816FC0 and dword ptr [ebp-4], 0
7C816FC4 push 4
7C816FC6 lea eax, [ebp+8]
7C816FC9 push eax
7C816FCA push 9
7C816FCC push 0FFFFFFFEh
7C816FCE call ds:__imp__NtSetInformationThread@16
7C816FD4 call dword ptr [ebp+8] ; this call executes code at EntryPoint of PE file;
7C816FD7 push eax ; dwExitCode
7C816FD8
7C816FD8 loc_7C816FD8:
7C816FD8 call _ExitThread@4
7C816FDD nop
7C816FDE nop
So in the stack we have 7C816FD7
So we have address from kernel32.dll, then we parsing it for getting exports, this is must be clear, if you know PE files stucrure.
p.s this method will no work with dll files because DllMain not executing with CreateProcess function.
Quotethen we parsing it for getting exports
yes sir,I finally got it.Thank you very much.
One more question,how did you get the code for the createprocess function.Just give me the idea and I will do the remaining research.Thanks.
is it just me who has a bad feeling of the direction of this code?
QuoteThis is old known method, by getting address of kernel32.dll from stack.
This method,is it applicable on all the versions of Windows?
i am not hearing any good reason why this topic should continuie so it is being locked.