Autor
|
Tema: Ejecución de Archivos desde Memoria [Base Relocation] (Leído 20,841 veces)
|
[Zero]
Wiki
Desconectado
Mensajes: 1.082
CALL DWORD PTR DS:[0]
|
Pero estás usando el primero o el segundo ejemplo? Yo tuve problemas con el primero pero lo solucioné con RtlAdjustTokenPrivileges, dando permisos a esa zona de SeDebugPrivilege. Con el primero no tuve problema, VirtualAlloc debería de dejar bien los permisos en esa zona, prueba a llamar a VirtualProtect a ver, pero es extraño . Saludos
|
|
|
En línea
|
“El Hombre, en su orgullo, creó a Dios a su imagen y semejanza. Nietzsche
|
|
|
plaganegra
Desconectado
Mensajes: 4
|
use VirtualProtect y RtlAdjustTokenPrivileges pero nada. A que te refieres con el primero o el segundo ejemplo, no se cual es cada uno De pronto uno es el que llamaste Loader y el otro es el ExecutableRunner, el que carga el loader? Saludos
|
|
|
En línea
|
|
|
|
[Zero]
Wiki
Desconectado
Mensajes: 1.082
CALL DWORD PTR DS:[0]
|
Si te fijas en el post principal hay dos apartados, un Ejecucion de Archivos con Relocation Table y otro sin ella. Por lo que dices del "Loader" supongo que te bajaste el segundo. Ese código es bastante inestable, tendrás que depurarlo bastante si quieres que funcione con todos los ejecutables. Por ejemplo falla obteniendo las apis de la IAT y al cargar la IAT, y supongo habrá algun otro fallo . Lo mejor es que intentes hacer uno de 0 basándote en ese, ya que no es un código ejemplar . Saludos
|
|
|
En línea
|
“El Hombre, en su orgullo, creó a Dios a su imagen y semejanza. Nietzsche
|
|
|
SoiundTrip
Desconectado
Mensajes: 1
|
Oh,it's really cool advice)
|
|
|
En línea
|
|
|
|
The Swash
Desconectado
Mensajes: 194
Programmer
|
A mi parecer la dependencia exacta de que todas las direcciónes físicas sean realocadas da un porcentaje muy alto de fallar al cargar un ejecutable en otro espacio de memoria diferente a su ImageBase, tenía que prácticar Relocations así que decidí intentarlo en Delphi y vaya trabajo me ha dado. Gracias [Zero] IMAGE_IMPORT_DESCRIPTOR = packed record OriginalFirstThunk: DWORD; TimeDateStamp: DWORD; ForwarderChain: DWORD; Name: DWORD; FirstThunk: DWORD; end; IMAGE_RELOCATIONS = packed record PageRVA: DWORD; Size: DWORD; end; type TArrayOfByte = array of byte; TArrayOfISH = array of TIMAGESECTIONHEADER; PIMAGEIMPORTDESCRIPTOR = ^IMAGE_IMPORT_DESCRIPTOR; PIMAGERELOCATIONS = ^IMAGE_RELOCATIONS; function RVATOOFFSET(RVA:DWORD): DWORD; var i,n: integer; begin for i:= 0 to IFH.NumberOfSections-1 do begin n:= (ish[i].VirtualAddress + ish[i].SizeOfRawData)-RVA ; if n > 0 then begin Result:=(RVA - ish[i].VirtualAddress) + ish[i].PointerToRawData; break; end; end; if RVA < ish[0].VirtualAddress then Result:= RVA; end; procedure Execute(); var IDH: PIMAGEDOSHEADER; IOH: PIMAGEOPTIONALHEADER; IDD: Array[0..15] of PIMAGEDATADIRECTORY; IID: PIMAGEIMPORTDESCRIPTOR; IR: PIMAGERELOCATIONS; aBuffer: TArrayOfByte; FileLen: DWORD; hFile: THANDLE; BytesRead: DWORD; Signature: PDWORD; i: DWORD; Acumulador: DWORD; BaseAddress: Pointer; lFunction: PDWORD; TempAddress: DWORD; EP: DWORD; aBlock: DWORD; rBlock: PWORD; dType: DWORD; Offset: PDWORD; Delta: DWORD; rOffset: DWORD; Ordinal: DWORD; GPA: function(hModule: Cardinal; Ordinal: Cardinal): Pointer; stdcall; begin hFile:= CreateFileA('C:\Archivos de programa\Opera\opera.exe',GENERIC_READ, FILE_SHARE_READ,nil, OPEN_EXISTING,0,0); If hFile <> INVALID_HANDLE_VALUE then begin FileLen:= GetFileSize(hFile,nil); SetLength(aBuffer,FileLen); ReadFile(hFile,aBuffer[0],FileLen,BytesRead,nil); end; GPA:= GetProcAddress(GetModuleHandle('kernel32'),'GetProcAddress'); CloseHandle(hFile); IDH:= Pointer(aBuffer); if IDH.e_magic = IMAGE_DOS_SIGNATURE then begin Signature := @aBuffer[IDH._lfanew]; if Signature^ = IMAGE_NT_SIGNATURE then begin IFH:= @aBuffer[IDH._lfanew + 4]; IOH:= @aBuffer[IDH._lfanew + 24]; Acumulador:= 0; for i:=0 to 15 do begin IDD[i]:= @aBuffer[IDH._lfanew + 120 + Acumulador]; Acumulador:= Acumulador+8; end; SetLength(ISH, IFH.NumberOfSections-1); Acumulador := 0; for i:=0 to IFH.NumberOfSections-1 do begin CopyMemory(@ISH[i], @aBuffer[IDH._lfanew + 248 + Acumulador], 40); Acumulador:= Acumulador + 40; end; BaseAddress:= VirtualAlloc(nil, IOH.SizeOfImage, MEM_RESERVE or MEM_COMMIT, PAGE_EXECUTE_READWRITE); CopyMemory(BaseAddress, @aBuffer[0], IOH.SizeOfHeaders); for i:=0 to IFH.NumberOfSections-1 do begin CopyMemory(Pointer(DWORD(BaseAddress)+ISH[i].VirtualAddress), @aBuffer[ISH[i].PointerToRawData], ISH[i].SizeOfRawData); end; Delta:= DWORD(BaseAddress) - IOH.ImageBase; rOffset:= RVATOOFFSET(IDD[5].VirtualAddress); IR:= @aBuffer[rOffset]; While(IR.PageRVA <> 0) do begin aBlock:= (IR.Size - 8)div 2; rBlock:= Pointer(DWORD(IR) + 8); While(aBlock > 0) do begin dType:= (rBlock^ and $F000) div $1000; Offset:= Pointer(DWORD(rBlock^ and $FFF) + IR.PageRVA + DWORD(BaseAddress)); if dType = 3 then begin Offset^:= Offset^ + Delta; end; rBlock:= Pointer(DWORD(rBlock)+ 2); aBlock:= aBlock - 1; end; IR:= Pointer(DWORD(IR)+ IR.Size); end; IID:= @aBuffer[RVATOOFFSET(IDD[1].VirtualAddress)]; While(IID.Name <> 0) do begin lFunction:= Pointer(DWORD(BaseAddress) + IID.FirstThunk); While(lFunction^ <> 0) do begin if lFunction^ > $80000000 then begin Ordinal:= lFunction^-$80000000; TempAddress:= DWORD(GPA(LoadLibraryA(@aBuffer[RVATOOFFSET(IID.Name)]),Ordinal)); end else begin TempAddress:= DWORD(GetProcAddress(LoadLibraryA(@aBuffer[RVATOOFFSET(IID.Name)]),@aBuffer[RVATOOFFSET(lFunction^+2)])); end; lFunction^:= TempAddress; lFunction:= Pointer(DWORD(lFunction)+4); end; IID:= Pointer(DWORD(IID)+20); end; EP:= IOH.AddressOfEntryPoint + DWORD(BaseAddress); asm mov eax, EP jmp eax; end; end; end; end;
PD: Algunos errores corregidos, añadido soporte para importación por ordinales.
|
|
« Última modificación: 4 Junio 2011, 17:03 pm por The Swash »
|
En línea
|
|
|
|
roilivethelife
Desconectado
Mensajes: 54
|
¿Seria posible que resubieseis los links? Gracias y un saludo
|
|
|
En línea
|
|
|
|
[Zero]
Wiki
Desconectado
Mensajes: 1.082
CALL DWORD PTR DS:[0]
|
Que faena, no conservo los archivos, si alguien los conserva y los pudiera resubir sería perfecto. De todas formas, con el código puedes compilarlo perfectamente, croe que no faltaba nada, incluso el ejemplo está.
Saludos
|
|
|
En línea
|
“El Hombre, en su orgullo, creó a Dios a su imagen y semejanza. Nietzsche
|
|
|
roilivethelife
Desconectado
Mensajes: 54
|
Que rabia... yo lo tuve hace tiempo en el pc pero formateé Intentaré compilarlo entonces, pero ¿que programa uso? Visual Studio? salu2
|
|
|
En línea
|
|
|
|
[Zero]
Wiki
Desconectado
Mensajes: 1.082
CALL DWORD PTR DS:[0]
|
Sí, con Visual Studio, la 2008 o la 2010 deberían de ir perfectas.
Saludos
|
|
|
En línea
|
“El Hombre, en su orgullo, creó a Dios a su imagen y semejanza. Nietzsche
|
|
|
Karman
|
hay dos problemas con el código, 1º que no tiene en cuenta los imports que usan ordinal en vez de nombres y el segundo son los Forwarder imports acá tienen una versión que hice de un "full" GetProcAddress manual: FARPROC WINAPI GetProcAddress(HMODULE hModule,LPCSTR lpProcName){ DWORD index,dwExportSize,dwOrdinal=0; if(!hModule)return NULL; PIMAGE_DOS_HEADER pDosHeader; PIMAGE_NT_HEADERS pNTHeader; PIMAGE_EXPORT_DIRECTORY pExportDir; pDosHeader=(PIMAGE_DOS_HEADER)hModule; if(pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE) return NULL; pNTHeader=RVAPTR(PIMAGE_NT_HEADERS,pDosHeader,pDosHeader->e_lfanew); if(pNTHeader->Signature!=IMAGE_NT_SIGNATURE) return NULL; pExportDir=RVAPTR(PIMAGE_EXPORT_DIRECTORY,pDosHeader,pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); dwExportSize=pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; if(!pExportDir) return NULL; PCHAR* pszName=RVAPTR(PCHAR*,pDosHeader,pExportDir->AddressOfNames); PDWORD pdwAddress=RVAPTR(PDWORD,pDosHeader,pExportDir->AddressOfFunctions); PWORD pwOrdinals=RVAPTR(PWORD,pDosHeader,pExportDir->AddressOfNameOrdinals); if(!pszName||!pwOrdinals||!pdwAddress) return NULL; if(HIWORD(lpProcName)==0){ // Look up by ordinal dwOrdinal=(LOWORD((DWORD)lpProcName)-pExportDir->Base); }else{ // Look up by name for(index=0;index<pExportDir->NumberOfNames;index++){ if(!lstrcmpA(RVAPTR(PCHAR,pDosHeader,pszName[index]),lpProcName)){ dwOrdinal=pwOrdinals[index]; break; } } } //Get Func Address DWORD dwFunction=RVAPTR(DWORD,pDosHeader,pdwAddress[dwOrdinal]); // Let's Check if is Forwarder if((dwFunction>(ULONG_PTR)pExportDir)&&(dwFunction<((ULONG_PTR)pExportDir+dwExportSize))){ CHAR ForwarderDllName[MAX_PATH],*ForwardImportName;USHORT len; ForwardImportName =strchr((LPSTR )dwFunction ,'.'); len=ForwardImportName++-(LPSTR)dwFunction; strncpy(ForwarderDllName ,(LPSTR )dwFunction ,len ); strcpy(&ForwarderDllName [len ],".dll"); // Find the module associated to it (should be already loaded) return GetProcAddress(GetModuleHandleA(ForwarderDllName),ForwardImportName); } return (FARPROC)dwFunction; }
capaz lo pueden adaptar... S2
|
|
« Última modificación: 8 Junio 2012, 06:03 am por Karman »
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
PUPE - Parcheador de archivos en ejecución y volcador de memoria
Ingeniería Inversa
|
ARGVC
|
1
|
4,079
|
23 Junio 2007, 03:40 am
por tena
|
|
|
Modificando memoria en tiempo de ejecucion C++
Ingeniería Inversa
|
.CPP
|
5
|
3,781
|
17 Septiembre 2008, 20:05 pm
por ...........
|
|
|
Denegar la ejecución desde el navegador
PHP
|
Servia
|
0
|
1,806
|
20 Diciembre 2009, 22:01 pm
por Servia
|
|
|
ayuda con problema c++ relocation truncated
Programación C/C++
|
+ 1 Oculto(s)
|
7
|
4,302
|
19 Mayo 2016, 01:44 am
por + 1 Oculto(s)
|
|
|
mover archivos con powershel desde un listado de archivos en variable de memoria
Scripting
|
erick_correa
|
1
|
1,929
|
18 Septiembre 2018, 01:26 am
por EdePC
|
|