I found this code while browsing through the examples that come with the masm32 package.
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.
; =======================================
; 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,
Call Get_Apis ; get kernel apis
Lea Eax, ; load user32.dll
Push Eax
Call
test Eax,Eax
jz Error_Exit
Mov ,Eax ; store result in 'default'
push 2 ; 4 api's in the user32 struc
pop Ecx
Lea Esi,
Call Get_Apis ; get user32 apis
Push -1
Call ; beep
Push 0
Call _t02
db "little test",0
_t02: Call _t01
db "MessageBox without imports, funny eh?",0
_t01: Push 0
Call ; messagebox
Error_Exit:
Push 0
Call ; get out
; ######################## get kernel ########################
; returns kernelbase and stores it in 'default' and 'kernel'
Get_Kernel:
Mov Ecx, ; get kerneladdr from stack
Kernel_Loop:
Xor Edx,Edx
Dec Ecx
Mov Dx,
Test Dx,0F800H
Jnz Kernel_Loop
Cmp Ecx,
Jnz Kernel_Loop
Mov ,Ecx
Mov ,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 ; addresses...
Push Ecx
Call Get_Api
Pop Ebx
Pop Ecx
Add Esi,Ebx
Mov ,Eax
Add Esi,4
Loop Api_Loop
Ret
; ######################## get api ########################
; default = dll base
; ecx = structure entry
Get_Api:
Mov Edx,
Add Edx, ; get default module
Mov Edx,
Add Edx,
Mov Edi, ;Get Addrofnames
Add Edi,
Mov Edi, ;Get Addrofnames
Add Edi,
Mov Eax, ;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, ;Get Addrnameord
Add Ecx,
Dec Ebx
Movzx eax, word ptr
Mov Ebx, ;Get Addroffunctions
Add Ebx,
Mov Eax,
Add Eax,
Ret
Not_Found:
Dec Edi
Loop_1:
Inc Edi
Cmp Byte Ptr ,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.
Gee, that code looks familiar.
This kind of code verges on breaching our Rules.
Please don't post this sort of code here again, at least not as a complete unit.
If you must, quote a few lines, ask specific questions, one at a time.
Don't expect anyone to explain the complete sourcecode to you.
You can get help, we just don't want to encourage (or be seen to encourage) malicious code and/or malicious coders.
This kind of code verges on breaching our Rules.
Please don't post this sort of code here again, at least not as a complete unit.
If you must, quote a few lines, ask specific questions, one at a time.
Don't expect anyone to explain the complete sourcecode to you.
You can get help, we just don't want to encourage (or be seen to encourage) malicious code and/or malicious coders.
Sir
this code is NOT malicious(if it's malicious why it is distributed with the masm7 package that I downloaded a few months back).
it just displays a message box and nothing else but it does this WITHOUT importing any libraries and that is what I want to understand.
What I understand about this code is that it find out the address of the message box api in the place where dll is loaded when the OS is loaded,but I don't understand that how this code finds the address where the dll is loaded.So just point out to me how THAT part of code works.
this code is NOT malicious(if it's malicious why it is distributed with the masm7 package that I downloaded a few months back).
it just displays a message box and nothing else but it does this WITHOUT importing any libraries and that is what I want to understand.
What I understand about this code is that it find out the address of the message box api in the place where dll is loaded when the OS is loaded,but I don't understand that how this code finds the address where the dll is loaded.So just point out to me how THAT part of code works.
Sir
this code is NOT malicious(if it's malicious why it is distributed with the masm7 package that I downloaded a few months back).
That is not saying much. The legality of the package itself is questionable, at best.
it just displays a message box and nothing else but it does this WITHOUT importing any libraries and that is what I want to understand.
On that point I would not consider it malicious. However, please do adhere to Homer's warning and don't post whole chunks of code like that when it obviously originates from a current/former malware developer.
Search engines are fickle creatures ;)
What I understand about this code is that it find out the address of the message box api in the place where dll is loaded when the OS is loaded,but I don't understand that how this code finds the address where the dll is loaded.So just point out to me how THAT part of code works.
You'll need intimate knowledge of the Portable Executable format to understand what is going on here. The code is using the base address of the program itself to find the hard-coded import locations... which is actually not an entirely accurate explanation... but it should point you in the right direction.
FYI: That code method will probably be tagged by any decent anti-virus software, since there is a good deal of malware-based methods being utilized. If you really want to do a Library-less call in ASM, look into INT 0x2E and the Windows System Call mechanism :)
shakuni,
You are right that the code is not malicious, the problem is that this code uses a technique that borders on the edge of malicious coding. "Portable coding" is very rarely used in anything other than viruses or shellcode, both of which are against the rules of this forum. There are legitimate uses but too few to overlook malicious ones. If you read the comment, Mob even states what he was using this code in relation to, "i'm working on something like a executable patcher right now so portable code was very interesting for me". This would fall under reverse engineering and is also not allowed. This is why Homer asked for you not to post the complete source here again. Mob was a well known virus/trojan author and as for why hutch decided to include code by him in his package I can't answer that, you'd have to ask him.
Regards,
Bryant Keller
You are right that the code is not malicious, the problem is that this code uses a technique that borders on the edge of malicious coding. "Portable coding" is very rarely used in anything other than viruses or shellcode, both of which are against the rules of this forum. There are legitimate uses but too few to overlook malicious ones. If you read the comment, Mob even states what he was using this code in relation to, "i'm working on something like a executable patcher right now so portable code was very interesting for me". This would fall under reverse engineering and is also not allowed. This is why Homer asked for you not to post the complete source here again. Mob was a well known virus/trojan author and as for why hutch decided to include code by him in his package I can't answer that, you'd have to ask him.
Regards,
Bryant Keller
The method for finding the functions consists in getting KERNEL32.DLL address from the stack (the return address), and later doing some memory traversing to find out where the kernel32's export table is located and take LoadLibrary address from there.
Note however that this method is unreliable, Windows 2000 needs KERNEL32.DLL imported directly or indirectly by another API that you import from the import table, otherwise the EXE is not executed at all. This method actually is ancient, I can't remember where I see it the first time (iczelion?). Well, there is a difference with the method I saw, while your example seems to get all addressess on its own, the other just used it to get LoadLibary&GetProcAddress but this one abuses the fact that the instance returned by LoadLibrary is in fact a pointer to the loaded library location.
PS: Sorry SpooK, I'm repeating you in some aspects but to lazy to edit :P. BTW, what slow I am today :S "Warning - while you were typing 2 new replies have been posted. You may wish to review your post."
Note however that this method is unreliable, Windows 2000 needs KERNEL32.DLL imported directly or indirectly by another API that you import from the import table, otherwise the EXE is not executed at all. This method actually is ancient, I can't remember where I see it the first time (iczelion?). Well, there is a difference with the method I saw, while your example seems to get all addressess on its own, the other just used it to get LoadLibary&GetProcAddress but this one abuses the fact that the instance returned by LoadLibrary is in fact a pointer to the loaded library location.
PS: Sorry SpooK, I'm repeating you in some aspects but to lazy to edit :P. BTW, what slow I am today :S "Warning - while you were typing 2 new replies have been posted. You may wish to review your post."
Please don't post this sort of code here again, at least not as a complete unit.
I am sorry to post the whole code,I'll not do it again.
This kind of code verges on breaching our Rules.
the problem is that this code uses a technique that borders on the edge of malicious coding.
Regarding the malicious background of the author and his code,I did'nt knew about it.
Next time I will do proper research before posting anything.
"Portable coding"
Sir,Can you please tell me more abut this?I've been reading that assembly language is NOT portable.
This method actually is ancient
Sir,What are the "new" methods of writing "portable" assembly code?
there is a difference with the method I saw
Sir,Can you please tell me what was the other methods?
Sorry for so much questioning,but please try to understand my situation because I am still in the learning phase.
Don't know what new methods are available, I just said that trick was published long time ago (the variation I saw at least).
About portability (I talked about it apart of the Windows 2000 remark?), the problem with this method is that is not reliable across Windows versions (here the loss of portability comes). ASM is not portable, but by using these technics you are making your executable even less portable while executables that imports "in the right way"TM works on more versions and even in future versions (unless Microsoft decide in future to break compatibility with software designed for earlier versions of Windows).
To sumarize, this method is not documented by Microsoft and hence you have no warranties that it will work OK always. Import APIs in the usual way. If you use fasm, by just doing
Automatically builds the import table for you. You can use a sightly lower level if you want or really constructing your import table by yourself, check the examples inside the package.
About portability (I talked about it apart of the Windows 2000 remark?), the problem with this method is that is not reliable across Windows versions (here the loss of portability comes). ASM is not portable, but by using these technics you are making your executable even less portable while executables that imports "in the right way"TM works on more versions and even in future versions (unless Microsoft decide in future to break compatibility with software designed for earlier versions of Windows).
To sumarize, this method is not documented by Microsoft and hence you have no warranties that it will work OK always. Import APIs in the usual way. If you use fasm, by just doing
include 'win32ax.inc'
.code
start:
invoke MessageBox, 0, "Hello", "Hello", 0
invoke ExitProcess, 0
.end start
Automatically builds the import table for you. You can use a sightly lower level if you want or really constructing your import table by yourself, check the examples inside the package.
The fix for win2k systems (assuming you can detect the OS without any api, which I can) is, as sp00k suggested, to use an int 2e call to get k32 loaded, and then everything is peachy.
Again, the key here is the ability to detect which OS the code is running on WITHOUT using any api.
Again, the key here is the ability to detect which OS the code is running on WITHOUT using any api.
What's the point in no-imports-whatever, anyway? You need to import (or end up importing) from kernel32, otherwise your app will silently fail to load on win2k.
Using int2e/syscall doesn't sound like a too great idea to me either, there's no guarantee that syscall numbers won't be swapped around on a service pack or whatever.
Using int2e/syscall doesn't sound like a too great idea to me either, there's no guarantee that syscall numbers won't be swapped around on a service pack or whatever.
What's the point in no-imports-whatever, anyway? You need to import (or end up importing) from kernel32, otherwise your app will silently fail to load on win2k.
Using int2e/syscall doesn't sound like a too great idea to me either, there's no guarantee that syscall numbers won't be swapped around on a service pack or whatever.
That's the whole point of having such DLL wrappers :P
What's the point in no-imports-whatever, anyway? You need to import (or end up importing) from kernel32, otherwise your app will silently fail to load on win2k.
Using int2e/syscall doesn't sound like a too great idea to me either, there's no guarantee that syscall numbers won't be swapped around on a service pack or whatever.
That's the whole point of having such DLL wrappers :P
Exactly - and using them :)
Again, the key here is the ability to detect which OS the code is running on WITHOUT using any api.
To detect NT based systems (ignoring NT4 you will get 2K+)
fs mov eax, [18h] ; Test for NT
cmp eax, 7FFDE000h
setne B ; set the 9x flag based on the EFLAGS register
Donkey
Iirc you can also check for 9x vs. NT by checking if you have LDT or GDT segments...
But again, this is pretty dirty stuff, might fail running under emulation, etc.
But again, this is pretty dirty stuff, might fail running under emulation, etc.