
ADVERTISE by Guardian Angel: This article is not 'designed for idiots who do play the sorcerer's apprentice. This article 'aimed at those who love knowledge.
A call to friends in Italy that deal with information technology: Internet, 16 June 2009 Presidents of Parliamentary Groups Senate ROME
Dear President,
the 1415A ddl approved in the House of Deputies on 11 June us has, in many quarters, raised many doubts and misgivings as to its constitutional legitimacy and, more generally, the appropriateness of regulatory interventions that, through it, be carried out.
There is, however, a profile, so far, remained in the shade and little in-depth discussions of these days: the contents of paragraph 28. 1, whose unfortunate wording - also admitted that this was not the actual will of the extensor - is likely to determine an unacceptable restriction of freedom of expression that push online, quickly, to Italy in a position more rearward than it currently occupies (it's Forty-fourth) in the international ranking on freedom of information.

I urge you to sign the petition found at this address: http://www.firmiamo.it/norettifica otherwise of those articles, in Italy will only be a pale memory.
(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)
Dll Injection Part II

Welcome back...
Last time i explained to you what DLL Injection is.
"Injecting a dll into a running process, is inserting a dll into the process's address space..
as you all -should- know is that when you load a dll, it goes to your address space, which means that,
your variables/memory in general, are all accessible with normal pointers by the dll itself."
I also explained that you need to have a knowlege of the following things:
1) Memory management...You need to know how windows manages it's memory
2) PE Headers <--the most important thing if you're doin this in win9x/ME --
3) Basic debbuging APIs...These are some apis that allow you do debug a certain app
4) enough knowlege of asm...and OPCODES of instructions I also said that my tutorial is compatible with all versions of windows.
So don't go posting me saying 'CreateRemoteThread() will do all of what you have just done'...I told you that i'm doing this tutorial for everyone. And if it would make you happy, i will add some information about the functions you can use in higher versions than WinME/9x And I'm doing the same thing I did last time. I am "NOT" pasting full code in this tutorial either. No one is stupid enough like me to even think of posting such brief article about something that is hard to learn if you had no documentation. So, therefore, it is hard to accept distributing it to the public. Programmers all think that they got tired for searching all this. They're not going to let their sweat go to waste.
So they keep telling you "GO RESEARCH ON YOUR OWN",, and probably kick you off their chat rooms. So, i'm probably doing the same thing ::D::D::D::D -- Ok you should have made that dll file that i told you about last time.
I'll assume the dll is in C:\\NazSoft\\DLLINJ32.dll (Dll to inject) Remember also, that i asked you to make an exe project, that puts the dll into its address space using LoadLibrary() Now, we're going to do something else. FORCE an app to load the dll into its address space. That's what i did to mirc.exe. But first, i need you to create the exe file! Make an exe file, that has a dialog box with a button. If the button was clicked, this happens: MessageBox( 0, "Let's see whether this function gets intercepted or not?!!", "Hello world!", MB_OK ); I'll assume you named the exe file, C:\\NazSoft\\MYMSGBOX.exe (Target process) OK, For the first section of this part, we'll inject DLLINJ32.dll into MYMSGBOX.exe in 2 different ways, 1) Using
CreateProcess().... The injector (the program that will inject) will create a new process of that program. And simply inject using the debugging facilities. Recall from PART I: "Talking at a lower level, what my API Spy exactly does is 'debug' the chosen running process and thus suspending all of its threads. It will then use some special API functions to be able to read it's private address space...
(Read/WriteProcessMemory()) It will seek some place to inject some code into. It is ASM code ofcourse. What this ASM code does is: LoadLibrary("DLLtoINJECT.dll"); And add a breakpoint after the code. Then simply let the process run, starting with the beggining address of the injected code. When the breakpoint is reached, the threads are suspended again and the API Spy restores whatever bytes it has modified and restores all the registers and thus continuing with normal execution like if nothing happened. Kind of like hypnotising someone, slapping him, and bringing him back. He'll have no idea of what just happened. Anyway, The loaded DLL does its job normally. Simple as that." 2) Use a method to inject the dll into a thread, by knowing just it's ThreadId, ProcessId, and possibly base address of the program. This method is used to inject a dll into an ALREADY running process.
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
--However, there is one problem in both of these ways. To do all that, i use the debugging method. Which is not such a good idea. I'll explain why later, and an alternative that can be used in future versions of windows. Actually, WinME had my problem solved, and then NT3.1 made it better, then came WinXP, which made it even better than ever before!... We'll talk about it later --- Let's make the (Injector) --- #define TargetApp "C:\\NazSoft\\MYMSGBOX.exe" #define DLL "C:\\NazSoft\\DLLINJ32.dll" *** | | | | This is the CreateProcess() method: (*)(*)(*)(*)(*)(*)(*)
You use CreateProcess() to start the program, with DEBUG_ONLY_THIS_PROCESS flag set. This will let you use the windows' special debugging functions. If you read the link i gave you in part one about Basic Debugging, this should be no problem, and you must have seen that DebugActiveProcessStop() works _ONLY_ in WinXP and above...(There is no above. Maybe Longhorn? the new revolutionary version of blindows? i mean, windows?) This is one advantage of XP over other OS's...
(*)(*)(*)(*)(*)(*)(*)
So don't go saying, XP SUX XP SUX XP SUX This makes it a REAL problem, because if you are debugging a process, and terminate your own process, the debugged process will be terminated also, and there is no way to stop it from happening. Even visual studio 6's debugger can't keep an application being debuged from staying alive, upon closure of VC++, It always gives you a msgbox: "This command will stop the debugger. Do you wish to continue?"
--(*)(*)(*)(*)(*)(*)(*)
There you see the problem that debugging a process has, which XP fixed...This is why i said "...WinXP, which made it even better than ever before!..." :)... Actually, it didn't make it better than ever before, because CreateRemoteThread(), supported in NT3.1 and over, makes all of what i'm doing simpler. We'll talk about it later...
-- (*)(*)(*)(*)(*)(*)(*)
After you create the process, windows' loader will automatically set a break point, right before the process starts execution(because of the DEBUG_ONLY_THIS_PROCESS flag). So what you do is use WaitForDebugEvent(), and ContinueDebugEvent() to get notifications from windows, for a debugging event to occur in a process being debugged. One of them, is a breakpoint.
(*)(*)(*)(*)(*)(*)(*)
WaitForDebugEvent() just sits there waiting for an event, then suspends the execution of the thread, and returns.. It's your job to check it's return values and handle the events that you want. And then use ContinueDebugEvent() to let it continue execution.
(*)(*)(*)(*)(*)(*)(*)
--You need to keep waiting, until the target process exits, then you can exit. Because as i said, you can't stop debugging unless you terminate the target process(except in WinXP) When the first breakpoint occurs, you know that the process has been loaded in memory. Now, you need the Handle of the process, and the handle of the main thread (or any thread)
It's all gettable through CreateProcess's PROCESS_INFORMATION parameter(pInfo.hProcess, pInfo.hThread) Now that you have the process's handle, you can use ReadProcessMemory() and WriteProcessMemory() to read/write bytes into/out of the memory of the target process. (Ofcourse, you're not required to pause execution of the process in order to use these two functions, however in our case, you ARE required to ) "The process whose address space is read is typically, but not necessarily, being debugged. " is what MSDN had to say. I'll tell you why we need to pause execution. Now you know how you can use ReadProcessMemory(), and WriteProcessMemory(). What you should do is this. You need your knowlege of PE/COFF headers to find a writable address in the process's memory.
Once you have found it, you will have no problem in changing it's contents, whether it was required by the target process or not, because as i said before, the execution has been suspended, so the process won't find out that you have changed it's memory, until after it continues execution... but it will be too late at that time, cause you will have already restored whatever it was that you have changed. Just like hypnotising...
When you find a writable memory, you need to use your knowlege of asm, and the OPCODES of the instructions inorder to use WriteProcessMemory() to write in the asm instruction, which will call LoadLibrary() inorder to insert the DLL into it's address space. (Remember the exe program in part I? When it used LoadLibrary(), the MessageBox() function automatically got intercepted,
This is what should happen here. Ofcourse the dll that we made is not so good, because it has no function to restore the address of the import table that it changed. So it's your job to change the dll -if you like- and save the original address of the MessageBox() function, before chagning it to the entry point of the MyMsgBox() function, so that when you need to free the dll, you'd be able to restore the entry point of the MessageBox() function, from the entry point it has been set to ( MyMsgBox() in DLLINJ32.DLL) back to it's original entry point ( MessageBox() in USER32.DLL ) )
Ofcourse, this is not so required, because you might just leave the dll into the process's address space for ever. And when the process exits, no need to restore, cause IT EXITED. You haven't patched the exe. So everything will be restored back to it's original next time the program is started Ok, so you wrote in the asm instructions. Now, what they do is call LoadLibrary() and then breakpoint (INT 3h --OPCODE 0xCC) So that the debugger would recv a breakpoint event inorder to restore the bytes that were changed
--If you have enough knowlege of asm, you'll know that EIP is the address in memory of the current instruction being run. When you write the asm code in the target process, you need to change (after saving) the EIP register to the offset of the first byte of the asm instructions you have written in the memory address space of the process.
Then when break point occurs, restore the memory, and restore EIP to it's original address, so that the process would continue execution, like if nothing happened! You can use GetThreadContext() and SetThreadContext() in order to change/get the values of registers/flags of a running process. And these two functions "REQUIRE" the _thread_ "Not the process" to be suspended. The two functions take a thread handle, not a proces handle. Because a process can have more than one thread, a problem that might occur is that a thread will be suspended, but other threads are still running. This will wreck havoc in the system. But fortunatelly, The debugging functions will suspend the WHOLE process from running.
There is some other method i wanted to use, (other than debugging) which will have THIS problem. Because it doesn't suspend the process's execution, it will only suspend the execution of ONE thread.
(*)(*)(*)(*)(*)(*)(*)
That's why OpenThread() isn't supported in 9x, because Microsoft is afraid someone would get a thread handle, suspend it, and wreck havoc. But somehow, i donno why, WinME supports it, so do later versions...maybe Microsoft fixed something? or i donno...
This isn't our subject right now anyway... (I like writing confusing text..) ___ **WARNING**___**WARNING**___**WARNING**___**WARNING**___**WARNING**___**WARNING***
The following two paragraphs are irrelevant, so don't confuse your self, skip them for now.. ___ **WARNING**___**WARNING**___**WARNING**___**WARNING**___**WARNING**___**WARNING***
Anyway, i really think the debugging way is the best, if you can't use CreateRemoteThread()..
But if you found a way to suspend the whole thread, without the need of debugging, i think we can make the asm instructions give some notification to a FileMap (Shared memory between processes) that it has successfully loaded, so that the injector app would restore what it had chagned, so that the process would continue execution. You can let the dll do this for you. But then comes another problem, when code is injected, and run, and the dll gets loaded, what if, in the process, the thread continued execution, and it needed the portion of memory that we edited?? THERE!!! Now we have a problem!..This might cause a crash.. But then you might let the dll create some executable in a temp dir, and suspend execution. Then the executable will restore bytes, and exit, then the dll shuld somehow find a way to notify it self that it can resume thread execution..
IT NEVER ENDS!!!!! FIX A PROBLEM, FIND ANOTHER ONE...the BEST solution instead of using all that crap is either through debugging, or using CreateRemoteThread()...debugging can't be stopped, unless in WinXP, but what's the use? You can use CreateRemoteThread() instead of debugging, in XP... You can't use it in 9x/ME,,but ah well...what to do? this is the life...
Win98 will be soon out of the market. 2k already is i think. Atleast MS promised that they will remove it. It's been a whole year since the deadline they have given, but seems like it's still in the market. Maybe i don't read news alot. I've got too much work, anyway..
-- So now you understood the debugging method in a verbal way. I'll explain more about it, in a "codish" way..
BUT FIRST! let me tell you this, inorder to use ReadProcessMemory(), for finding some writable memory... You need to know the base address of the target process! I'll tell you how later.. and also, to find a writable memory, you shuld read the sections of the programs... Read about 'sections' in PE header... i usually get section ".data" as the writable part..maybe some other app has some other section? i dono... Actually, I DO know. There are apps that have sections with different names. for example, programs compiled with borland have different section names, than programs compiled in msVC++ (Another project to have fun with is, to open all exes of different compilers, in your machine, and save their import table and section names... The PE/COFF header specs should help...) If you notice, in asm programs you set sections like .CODE .DATA etc... It's all the same... VC++ uses .text, .idata and .data instead (.text == .CODE, ,.data == .DATA, , .idata == Import table ) .edata == export table, etc... (*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*) (*)(*)(*) (*) INJECTING A DLL INTO AN ALREADY RUNNING PROCESS (*)(*)*)(*)(*)(*)(*)(*)(*)(*)
(*)(*)(*) (*)(*)(*)
(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)
And now you know all about The CreateProcess() method. The other method, injecting into an ALREADY running process,
you need to use OpenProcess() to get a process handle, from a ProcessId, then use DebugActiveProcess() to start debugging.
Read DebugActiveProcess() in msdn, you will find answers to many questions that might have been raised when i gave you
this function. I'm not going to show an example on this function. You're on your own. Sorry, wish i could help.
But i'm not giving you the butter.
Read the "Debugging a Running Process" section in Basic Debugging section in msdn.
"
To debug a process that is already running, the debugger should use DebugActiveProcess with the process
identifier retrieved by OpenProcess. DebugActiveProcess attaches the debugger to the active process.
In this case, only the active process can be ..... To detach from the process being debugged,
the debugger should use the DebugActiveProcessStop function.
"
-MSDN
DebugActiveProcessStop isn't supported in versions before WinXP......go cry baby :P
-----(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)
ok, i showed you how the second method works...
Now.. the inefficient method that i was talking about... Doing all this without debugging..
You can skip this section if you want, it's for more advanced readers...
What i had in mind (I won't give code samples for this either, but this time, not because you need to reasearch on your own,
but beacuse i havn't done any code of it. And you never know, maybe this method is so inefficient, that you can't use it?)
ok here goes:
From the processes and thread section, i saw these functions:
OpenProcess, OpenThread, SuspendThread, ResumeThread
Look, get proces handle from the first function..Thread handle from the second.
Suspend the thread, use GetThreadContext/SetThreadContext and Read/WriteProcessMemory to read/write asm code
and modify/restore the registers, then Resume thread...
the asm code, can't use breakpoints, cause the app isn't debugging it, so the dll shuold somehow send some notification,
and suspend it's own execution. Then when the app recieves the notification, it will let it resume, after restoring everything.
There is more to it than just that...but you need to use your own imaginations
----(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)
Somefunctions for you to look at, (interesting functions)
DebugBreak, DebugBreakProcess, DebugSetProcessKillOnExit, IsDebuggerPresent, GetStartupInfo, Sleep, SleepEx, SwitchToThread
ThreadProc, TlsAlloc, TlsFree, TlsGetValue, TlsSetValue
There are some issues i haven't talked about here. You might encounter them ___MIGHT___
so if you did, read about TLS,,,Thread Local Storage..it shuold help you through for process's with more than one thread
(TlsAlloc, TlsFree, TlsGetValue, TlsSetValue)
----(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)
You're probably mad at me like hell, and not voting for me, because i asked you to reasearch on your own.
Too bad :PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
kidding..i'm sorry dude, but i'm serious. These are issues that need work from the programmer him/her self.
You can't just let it away like that :( I'm sorry once again. Maybe if you email me(on my yahoo account)
I might help you more on this, or else, i'm sorry. Besides, i didn't have that much time to write all the code
in here..i'm truly sorry...and i applogize for any inconvenience this did.
Once again, i'm sorry
----(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)
Let's see what the asm code that needs to be injected shuold look like.
There are many different ways to code it's asm code..but this is my way.
and i like it like that.
{
mov eax, 0h ; change 0h to address to LoadLibrary()
mov ebx, 0h ; change 0h to offset to dll name (almost always at the end of this code comes the dll name)
; so it can be, offset of beggining of this code + the total size of the asm code. This points you
; to whatever that's after it. Which is, the dll name
push ebx ; Push parameter of LoadLibrary() into stack (dll name)
call eax ; call LoadLibrary()
pop ebx ; Pop ebx which was pushed -- if you don't do this, you'll get a funny scary error
; If you read about opcodeVOID's NakedFunctions,, and saw the asm instructions before and after
; high level functions,, there are the code(within them) that will check for whether you have restored what you have pushed into the stack
; so basically it's required, opcodeVOID :D :D :D But, he's still right, if you are an advanced programmer
; and know what you're doing, then you have no problem
;;; and also note that where you're writing this code, it is at it's lowest level, and there aren't
;;; code to check for this..a whole program destruction might occur without you knowing
; it's kind of like when you are sick, and probably have aids, and are dying, but don't have
; a nervous system to feel it. So, you won't feel pain, this might cause you to suddenly collapse and die :D
int 3h ; break point
; Immediately after this, comes the dll's whole path "C:\NazSoft\DLLINJ32.DLL" and don't forget the null character
}
These are the OPCODES:
{
char CodePage[4096] =
{ 0xB8, 00, 00, 00, 00, // mov EAX, 0h | Pointer to LoadLibraryA() (DWORD)
0xBB, 00, 00, 00, 00, // mov EBX, 0h | DLLName to inject (DWORD)
0x53, // push EBX
0xFF, 0xD0, // call EAX
0x5b, // pop EBX
0xcc // INT 3h
};
DWORD nob=15; //Number of bytes ^^^^^^
//comes right after this, the dll name...so just do this, strcpy(CodePage[nob], Dllname) to append the dll name..
the total size is (nob + strlen(Dllname) + 1) -- strlen retreives the string, without NULL character.
So you do +1, do also add the null character
------You might ask why i declared 4096 chars? well, a codePage is 4K,,,So i just did it,,,for,,,um,,,
no reason... :D :D
}
I'll give you some OPCODE lists with this tutorial for you to have use of..
You'll have fun reading it
--by the way, go to EFnet#C++ or #asm or #win32asm and ask for a full ebook of asm..
They shuld give you a free ebook called, "The art of assembly"
--
I suddenly changed my mind and added some tutorials with the .zip file :p
I even added some unneccessary stuff :P
--(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)
Here show you the code of CreateProcess() method:
--(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)(*)
declare these global vars:
CONTEXT OriginalContext; //Get/SetThreadContext's parameter
char OriginalCodePage[4096];
DWORD sizeofCP=0;
VOID* mySec; //my section...Offset of CodePage in the target process's memory, not this app's memory
BOOL InjectDLL_CreateProcess( char *TargetAPP, char *DLLTOINJECT )
{
BOOL B=FALSE, BREAK1=FALSE, BREAK2=FALSE;
STARTUPINFO sInfo;
PROCESS_INFORMATION pInfo;
DEBUG_EVENT dEvent;
DWORD ret;
ZeroMemory((VOID*)&sInfo, sizeof(sInfo));
B = CreateProcess(Filename, 0, 0, 0, FALSE, DEBUG_ONLY_THIS_PROCESS, 0, 0, &sInfo, &pInfo);
if(!B) return FALSE;
//-----
///
////
///// We need 3 things, ProcessHandle, ThreadHandle, and BaseOfImage (base address of executable file in memory)
////
///
//-----
HANDLE PHandle=pInfo.hProcess, THandle=pInfo.hThread; // Processhandle, Thread handle
VOID * BaseOfImage;
char DLLTOINJECT[] = "d:\\VCPrj\\MSNInject\\DLL\\Release\\DLL.dll";
while(1)
{
if( !(B = WaitForDebugEvent(&dEvent, INFINITE)) ) //Remember? -- dEvent is a structure that recv'es return of fucntion
return -1;
if(dEvent.dwDebugEventCode==CREATE_PROCESS_DEBUG_EVENT) //If the debug event was "Process has just been created"
{
BaseOfImage = dEvent.u.CreateProcessInfo.lpBaseOfImage; //Ok, now we have the base address of the exectable file in memory (remember before, when i said that i'll show you how to get it?)
}
if(dEvent.dwDebugEventCode==EXIT_PROCESS_DEBUG_EVENT) //if process terminated, then break the loop, so that you would exit function
break;
if(dEvent.dwDebugEventCode==EXCEPTION_DEBUG_EVENT)//Check for breakpoint
{
if(dEvent.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_BREAKPOINT)
{//It is a break point;
if(BREAK1==FALSE)
{//First Breakpoint occured
B = InjectDLL( pInfo.hProcess, pInfo.hThread, BaseOfImage,
DLLTOINJECT); //The magical function, comes after this function
BREAK1 = TRUE;
if(!B)
return FALSE;
}else if(BREAK2==FALSE)
{//Second breakpoint occured (asm instructions have been all done, and int 3h was reached
ret = RestoreOriginalCodePage( PHandle, THandle, 0); //another function to restore
if(ret==0) return FALSE; //uhoh!!! Big big big big error...you need to restore what you have written, but couldn't,,,,i'll leave it to you, cause i, my self donno what to do, other than terminate the target process :P
BREAK2=TRUE;
}
}else
{ //if an Exception occured, and it wasn't a break point, then say DBG_EXCEPTION_NOT_HANDLED
//Because you haven't handled the exception, so let lindows,,i mean, windows handle it..
ContinueDebugEvent( dEvent.dwProcessId, dEvent.dwThreadId, DBG_EXCEPTION_NOT_HANDLED);
continue;
}
}//end if
ContinueDebugEvent( dEvent.dwProcessId, dEvent.dwThreadId, DBG_CONTINUE);
//you don't need to handle event,,let it pass
}//end while()
}//end function
////////////////////
next function:
BOOL InjectDLL(HANDLE hProcess, HANDLE hThread, VOID* hModuleBase, char *DllName)
{//You must have debug access to hProcess (required for ReadProcessMemory() & WriteProcessMemory)
FARPROC LoadLibProc = GetProcAddress(GetModuleHandle("KERNEL32.dll"), "LoadLibraryA");
if(!LoadLibProc) return FALSE;
//This is the entry point addr of LoadLibrary()...It's usually, always the same for any process that loads kernel32.dll
//So unless there is some other explanation, i don't know
//But i personally found that this works all of the time
////////////////////////////////
char CodePage[4096] =
{ 0xB8, 00, 00, 00, 00, // mov EAX, 0h | Pointer to LoadLibraryA() (DWORD)
0xBB, 00, 00, 00, 00, // mov EBX, 0h | DLLName to inject (DWORD)
0x53, // push EBX
0xFF, 0xD0, // call EAX
0x5b, // pop EBX
0xcc // INT 3h
}; //i could have used structS instead, but unfortunatelly, because of many compilers' stupid padding, i didn't >:(
int nob=15; //no of bytes
char *DLLName; //DllName
DWORD *EAX, *EBX; //Look at codepage
DLLName = (char*)((DWORD)CodePage + nob); //Set the pointers
EAX = (DWORD*)( CodePage + 1); //
EBX = (DWORD*) ( CodePage + 6); //
strcpy( DLLName, DllName ); //copy dll name
*EAX = (DWORD)LoadLibProc; //EAX==LoadLibProc
*EBX = nob; // need to do this: *EBX = *EBX + (offset of CodePage)
////////////////////////////
sizeofCP = strlen(DllName) + nob +1; //remember this? --
//Here comes the complicated part, you can use CreateRemoteThread() instead of all this, actually, but unfortunatelly
//it isn't supported in all versions of windows...but i'll tell you how to use it after this code..
//I have an example code that i found from google groups
IMAGE_DOS_HEADER DOShdr;
IMAGE_NT_HEADERS *pNThdr, NThdr;
IMAGE_SECTION_HEADER SecHdr, *pSecHdr;
IMAGE_DATA_DIRECTORY DataDir, *pDataDir; //@@@@@@@@
DWORD dwD, dwD2, read, written;
CONTEXT Context; //GetThreadContext's parameter &&
BOOL B;
Context.ContextFlags = CONTEXT_CONTROL; //look at WINNT.h header file for more information
OriginalContext.ContextFlags = CONTEXT_CONTROL;
if(!GetThreadContext( hThread, &OriginalContext)) //Save original context -- remember that currently the process is totally suspended
{
dwD = GetLastError();
return FALSE;
}
// Check to see if we have valid Headers:
//
/////////Get DOS hdr
B = ReadProcessMemory(hProcess, hModuleBase, &DOShdr, sizeof(DOShdr), &read);
if( (!B) || (read!=sizeof(DOShdr)) ) return FALSE;
if( DOShdr.e_magic != IMAGE_DOS_SIGNATURE ) //Check for `MZ
return FALSE;
//Get NT header
B = ReadProcessMemory( hProcess,
(VOID*)((DWORD)hModuleBase + (DWORD)DOShdr.e_lfanew), &NThdr, sizeof(NThdr), &read);
if( (!B) || (read!=sizeof(NThdr)) ) return FALSE;
if( NThdr.Signature != IMAGE_NT_SIGNATURE ) //Check for `PE\0\0
return 0;
// Valid EXE header!
// Look for a usable writable code page: -- this is where you seek the sections for a usable section
//
/////
//
if( (dwD=NThdr.FileHeader.NumberOfSections) < psechdr =" (IMAGE_SECTION_HEADER*)" b="FALSE;" dwd2="0" iterate="" sections="" for="" part="" which="" shouldn="" modified="" whatsoever="" because="" nazsoft="" sez="" bit="" long="" super="" novel="" give="" information="" u="" know="" confused="" listen="" when="" say="" points="" addr="" info="" from="" as="" see="" base="" addresses="" dll="" file="" functions="" are="" same="" programs="" psechdr="" isn="" true="" just="" easier="" way="" don="" use="" casting="" opers="" want="" do="" make="" sure="" correct="" amount="" was="" characteristics="" writable="" section="" const="" idata="" import="" strcmpi="" ignore="" cases="" small="" t="" find="" usable="" code="" found="" virtualaddress="" mysec="(VOID*)(SecHdr.VirtualAddress" global="" where="" asm="" instructions="" shuold="" ebx="*EBX" also="" remember="" top="" of="" stuff="" can="" read="" will="" already="" saved="" re="" going="" thread="" we="" them="" now="" starts="" mega="" occurs="" god="" knows="" uh="" system="" crash="" occur="" try="" save="" memory="" might="" injected="" must="" call="" upon="" following="" context="" b="TRUE;" change="" eip="(DWORD)mySec;" would="" be="" funny="" get="" an="" error="" all="" that="" goes="" and="" ever="" ist="" hat="" chagned="" s="" ok="" go="" back="" second="" break="" point="" another="" function="" ret="RestoreOriginalCodePage(" big="" need="" restore="" you="" but="" couldn="" ll="" leave="" it="" cause="" my="" self="" donno="" what="" to="" other="" than="" terminate="" target="" process="" break2="TRUE;" so="" lets="" have="" look="" at="" notepad="" is="" giving="" me="" a="" headache="" right="" keeps="" saying="" not="" enough="" m="" typing="" the="" rest="" in="" com="" program="" i="" love="" this="" thing="" p="" return="" if="" 0=""> successful
// if -1 -> (0xFFFFFFFF) WriteProcessMemory returned FALSE
// else -> Amount of bytes written + 1
// (to get exact amount of bytes written, you must decrement return value by one!)
//
DWORD RestoreOriginalCodePage( HANDLE hProcess, HANDLE hThread, DWORD *outSize )
{
BOOL B;
DWORD written;
CONTEXT Context;
if(outSize) *outSize = sizeofCP; //Just for user's info
Context.ContextFlags = CONTEXT_FULL; //look at winnt.h
GetThreadContext( hThread, &Context); //Get current thread context
//This isn't required, it's just for you to check the return
//value of LoadLibrary()
////It is in the EAX register (Context.Eax)
B = WriteProcessMemory( hProcess, mySec, OriginalCodePage, sizeofCP, &written );
//Restore original codepage
if(!B) return -1;
if(written!=sizeofCP)
return written+1;
//Restore context (EIP)
B=SetThreadContext( hThread, (CONST CONTEXT*)&OriginalContext);
if(!B) return -1;
return 0;
}
OK ATLAST!!!!!1
so now we're done!
You've seen how to do all this,,,now let me tell you how CreateRemoteThread() works...
You can skip this if you want...
CreateRemoteThread:
The CreateRemoteThread function creates a thread that runs in the virtual address space of another process
HANDLE CreateRemoteThread(
HANDLE hProcess, // handle to process
LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
SIZE_T dwStackSize, // initial stack size
LPTHREAD_START_ROUTINE lpStartAddress, // thread function
LPVOID lpParameter, // thread argument
DWORD dwCreationFlags, // creation option
LPDWORD lpThreadId // thread identifier
);
Parameters:
hProcess
[in] Handle to the process in which the thread is to be created. The handle must have the PROCESS_CREATE_THREAD, PROCESS_QUERY_INFORMATION, PROCESS_VM_OPERATION, PROCESS_VM_WRITE, and PROCESS_VM_READ access rights. For more information, see Process Security and Access Rights.
lpThreadAttributes
[in] Pointer to a SECURITY_ATTRIBUTES structure that specifies a security descriptor for the new thread and determines whether child processes can inherit the returned handle. If lpThreadAttributes is NULL, the thread gets a default security descriptor and the handle cannot be inherited.
dwStackSize
[in] Specifies the initial size of the stack, in bytes. The system rounds this value to the nearest page. If this parameter is zero, the new thread uses the default size for the executable. For more information, see Thread Stack Size.
lpStartAddress
[in] Pointer to the application-defined function of type LPTHREAD_START_ROUTINE to be executed by the thread and represents the starting address of the thread in the remote process. The function must exist in the remote process. For more information on the thread function, see ThreadProc.
lpParameter
[in] Specifies a single value passed to the thread function.
dwCreationFlags
[in] Specifies additional flags that control the creation of the thread. If the CREATE_SUSPENDED flag is specified, the thread is created in a suspended state and will not run until the ResumeThread function is called. If this value is zero, the thread runs immediately after creation.
Windows XP: If the STACK_SIZE_PARAM_IS_A_RESERVATION flag is specified, the dwStackSize parameter specifies the initial reserve size of the stack. Otherwise, dwStackSize specifies the commit size.
lpThreadId
[out] Pointer to a variable that receives the thread identifier.
If this parameter is NULL, the thread identifier is not returned.
------
Return Values:
If the function succeeds, the return value is a handle to the new thread.
If the function fails, the return value is NULL. To get extended error information, call GetLastError.
Note that CreateRemoteThread may succeed even if lpStartAddress points to data, code, or is not accessible.
If the start address is invalid when the thread runs, an exception occurs, and the thread terminates.
Thread termination due to a invalid start address is handled as an error exit for the thread's process.
This behavior is similar to the asynchronous nature of CreateProcess,
where the process is created even if it refers to invalid or missing dynamic-link libraries (DLLs).
-----
Remarks
The CreateRemoteThread function causes a new thread of execution to begin in the address space of the specified process. The thread has access to all objects opened by the process.
The new thread handle is created with full access to the new thread. If a security descriptor is not provided, the handle may be used in any function that requires a thread object handle. When a security descriptor is provided, an access check is performed on all subsequent uses of the handle before access is granted. If the access check denies access, the requesting process cannot use the handle to gain access to the thread.
The thread is created with a thread priority of THREAD_PRIORITY_NORMAL. Use the GetThreadPriority and SetThreadPriority functions to get and set the priority value of a thread.
When a thread terminates, the thread object attains a signaled state, satisfying any threads that were waiting for the object.
The thread object remains in the system until the thread has terminated and all handles to it have been closed through a call to CloseHandle.
The ExitProcess, ExitThread, CreateThread, CreateRemoteThread functions, and a process that is starting (as the result of a CreateProcess call) are serialized between each other within a process. Only one of these events can happen in an address space at a time. This means the following restrictions hold:
1) During process startup and DLL initialization routines, new threads can be created, but they do not begin execution until DLL initialization is done for the process.
2) Only one thread in a process can be in a DLL initialization or detach routine at a time.
3) ExitProcess does not return until no threads are in their DLL initialization or detach routines.
Terminal Services: Terminal Services isolates each terminal session by design. Therefore, CreateRemoteThread fails if the target process is in a different session than the calling process.
Windows NT/2000/XP: Included in Windows NT 3.1 and later.
Windows 95/98/Me: Unsupported.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.
--------------------
ok i copied it from msdn to here :P
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&safe=off&threadm=cl8L4.162599%24bm.706013%40news1.alsv1.occa.home.com&rnum=2&prev=/groups%3Fq%3DLLProc%26hl%3Den%26lr%3D%26ie%3DUTF-8%26oe%3DUTF-8%26safe%3Doff%26selm%3Dcl8L4.162599%2524bm.706013%2540news1.alsv1.occa.home.com%26rnum%3D2
Have a look at that site
It's an example of CreateRemoteThread() somone wrote...
I hope it's explanable from there?
plz post, and tell me if there shuold be part III
to fulfill something i haven't said right now
i will be glad to
if i had time
thats it for now
my eyes are draining
ok, thank you for reading PART II of my tutorial on how to inject a dll...
quiz:
What is dll injecting? And are its uses? And how do you do it? please elaborate :D :D
cya
-NRR TGA (aka NazSoft)
-CrankHank|EFNet#C++
Write to:the-legions@mail.ru









































































































































0 commenti:
Posta un commento