您的位置:首页 > 编程语言

一个向别的进程插入dll的代码 .

2014-11-04 13:38 357 查看
--------- Functions in C ---------------

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) < 1 ) //Number of sections must be atleast 1...DUH!!!

return FALSE;//Section table: (after optional header)

pSecHdr = (IMAGE_SECTION_HEADER*)

(

((DWORD)hModuleBase + (DWORD)DOShdr.e_lfanew) +

(DWORD)sizeof(NThdr.FileHeader) +

(DWORD)NThdr.FileHeader.SizeOfOptionalHeader + 4

);//@@@@@@@@@@@@@ need to concentrate on this to understand..except the +4,,,i saw that it always needs this,, i spent an hour trying to fix an error, until i noticed this :P...So just do it

B=FALSE;

///////////////////////////////GetModuleHandle(0); //i explained what this does, in part I,,,but unfortunatelly, it's for the dll, not for this exe :P

for( dwD2=0 ; dwD2<dwD ; dwD2++ )

{//iterate sections to look for a writable part of memory and NOT .idata -- because .idata is the import table,,which shouldn't be modified whatsoever -- because NazSoft sez so! :P it's a bit of a long story,,I'm not a super novel to give
you all the information u need :P

if( !ReadProcessMemory( hProcess, pSecHdr, &SecHdr, sizeof(SecHdr), &read) )

return FALSE; //i know you might look confused of what you see here...

///////////////////But listen to me when i say that this is not wrong. it is correct

///////////////////pSecHdr points to addr in memory of a section's name,,but not the memory of MY process,

///////////////////but the memory of the other process. If you do *pSecHdr,, you'll get info from you're process

///////////////////mostly, it'll be the same as the other proceess, but if you look closer, you'll see that it's not

///////////////////Base addresses of all dll file's functions are the same in all programs

///////////////////So pSecHdr isn't a true pointer,, just an easier way (so that i don't need to use casting opers alot)

///////////////////to do what i want to do

if(read!=sizeof(SecHdr)) return FALSE; //Make sure correct amount was read in

if(

(SecHdr.Characteristics & IMAGE_SCN_MEM_WRITE) //writable section

&&

( strcmpi((const char*)SecHdr.Name, ".idata")!=NULL ) //not .idata (import data)

) //strcmpi -- the "i" == ignore cases (capital, small letters...)

{

B = TRUE;

break;//OK! found!!

}

pSecHdr++;

}

if(!B)

return FALSE; //couldn't find usable code page!

//

/////

//Found a section: (SecHdr.VirtualAddress + (DWORD)hModuleBase)

mySec = (VOID*)(SecHdr.VirtualAddress + (DWORD)hModuleBase); //Remember this global var?

//This is where the asm instructions shuold go

*EBX = *EBX + (DWORD)mySec; //also remember this??? look at the top of the function

if(!ReadProcessMemory( hProcess, mySec, OriginalCodePage, sizeofCP, &read) )

return FALSE; //Read the stuff in memory, so that you can restore it

if(read != sizeofCP)

return FALSE;

//so now, yuou will have already saved the memory that you're going to modify, and the thread's context (registers)

//we'll restore them later..

//Now starts the mega part! (If an error occurs here, god knows what might happen!

B = WriteProcessMemory( hProcess, mySec, CodePage, sizeofCP, &written);

if( (written!=0) && (written!=sizeofCP) ) //Uh oh!, System crash might occur now!

{//****EMERGENCY**** ****EMERGENCY**** ****EMERGENCY**** ****EMERGENCY****

WriteProcessMemory( hProcess, mySec, OriginalCodePage, sizeofCP, &written);

// Try to save what you can, and return back to memory

return FALSE; //might not have worked, so, big s***!

}

if((!B) || (written!=sizeofCP))

return FALSE;

//Ok, injected successfully,

//You MUST call function RestoreOriginalCodePage() function upon the following breakpoint!

Context = OriginalContext;

Context.Eip = (DWORD)mySec; //Change EIP

B = SetThreadContext(hThread, &Context); //Change EIP

if(!B) return FALSE; //Lol, it would be funny to get an error here,,,all that goes to waste, and you need to restore what ever it ist hat you chagned :S :S :S

return 1;

}

//OK go back to InjectDLL_CreateProcess() ... Look at the second break point section:

/*

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;

*/

OK, so lets have a look at RestoreOriginalCodePage():

*******

Notepad is giving me a headache right now, keeps saying not enough memory.. :P :P

*******

I'm typing the rest in c:/windows/edit.com program --i love this thing :P

//return values:

//

// 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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: