Autor
|
Tema: [C++] Inyección de código en memoria- Aplicación crashea (Leído 8,172 veces)
|
Kaxperday
Desconectado
Mensajes: 702
The man in the Middle
|
Hola buenas, hace pocos días estuve leyendo sobre el API hooking y de allí salté a la inyección de DLL, y más adelante pasé a la inyección de código, y ayudándome con un código que encontré en rohitab fuí dando forma a mi código y puse control de errores. Este es el link por si a alguien le interesa, me fue muy útil: http://www.rohitab.com/discuss/topic/39357-code-cave-injection-tutorial-c/El programa inyecta un MessageBox en la aplicación objetivo, tras salir el MessageBox y pulsar aceptar se cierra la aplicación objetivo. Desconozco el porqué, os dejo el código a ver si me podéis ayudar a saber: #pragma once #include <windows.h> #include <shlobj.h> #include <wininet.h> #include <tlhelp32.h> #include <shlwapi.h> typedef int (WINAPI* MsgBoxParam)(HWND, LPCSTR, LPCSTR, UINT); using namespace std; struct PARAMETERS{ DWORD MessageBoxInj; char text[50]; char caption[25]; int buttons; //HWND handle; }; DWORD GetPIDFromProcName(LPCWSTR procName); DWORD MyFunc(PARAMETERS * myparam); DWORD Useless(); bool Injecter(); DWORD GetPIDFromProcName(LPCWSTR procName) { PROCESSENTRY32 pe; HANDLE thSnapShot; BOOL retval; thSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (thSnapShot == INVALID_HANDLE_VALUE) { return 0; } pe.dwSize = sizeof(PROCESSENTRY32); retval = Process32First(thSnapShot, &pe); while (retval) { if (!lstrcmp(pe.szExeFile, procName)) { return pe.th32ProcessID; } retval = Process32Next(thSnapShot, &pe); } return 0; } static DWORD MyFunc(PARAMETERS * myparam){ MsgBoxParam MsgBox = (MsgBoxParam)myparam->MessageBoxInj; int result = MsgBox(0, myparam->text, myparam->caption, myparam->buttons); switch (result){ case IDOK: //code break; case IDCANCEL: //code break; } return 0; } static DWORD useless(){ return 0; } //debe ser static para que el compilador las ponga juntas y calcule bien el tamaño :) bool Injecter() { HANDLE proc = NULL; DWORD pID = NULL; if ((pID = GetPIDFromProcName(L"chrome.exe")) == NULL)// no GetTargetThreadIDFromProcName ^^ { return false; } if ((proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID)) == NULL) { return false; } char * mytext = "Hello by CodeCave!"; char * mycaption = "Injection result"; PARAMETERS data; //let's fill in a PARAMETERS struct HINSTANCE hUserModule = LoadLibraryA("user32.dll"); if (hUserModule == NULL) { CloseHandle(proc); return false; } data.MessageBoxInj = (DWORD)GetProcAddress(hUserModule, "MessageBoxA"); strcpy(data.text, mytext); strcpy(data.caption, mycaption); data.buttons = MB_OKCANCEL | MB_ICONQUESTION; DWORD_PTR size_myFunc = (DWORD_PTR)((LPBYTE)useless - (LPBYTE)MyFunc); LPVOID MyFuncAddress = NULL; if ((MyFuncAddress = VirtualAllocEx(proc, NULL, size_myFunc, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE)) == NULL) { CloseHandle(proc); return false; } if (WriteProcessMemory(proc, MyFuncAddress, (LPVOID)MyFunc, size_myFunc, NULL) == NULL) { VirtualFree(MyFuncAddress, 0, MEM_RELEASE); CloseHandle(proc); return false; } LPVOID DataAddress = NULL; if ((DataAddress = VirtualAllocEx(proc, NULL, sizeof(PARAMETERS), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)) == NULL) { CloseHandle(proc); return false; } if (WriteProcessMemory(proc, DataAddress, (LPVOID)&data, sizeof(PARAMETERS), NULL) == NULL) { VirtualFree(MyFuncAddress, 0, MEM_RELEASE); VirtualFree(DataAddress, 0, MEM_RELEASE); CloseHandle(proc); return false; } HANDLE thread = NULL; if ((thread = CreateRemoteThread(proc, NULL, 0, (LPTHREAD_START_ROUTINE)MyFuncAddress, DataAddress, 0, NULL)) == NULL) { VirtualFree(MyFuncAddress, 0, MEM_RELEASE); VirtualFree(DataAddress, 0, MEM_RELEASE); CloseHandle(proc); return false; } WaitForSingleObject(thread, INFINITE); VirtualFree(MyFuncAddress, 0, MEM_RELEASE); VirtualFree(DataAddress, 0, MEM_RELEASE); CloseHandle(thread); CloseHandle(proc); cout << "Injection completed!" << endl; return true; }
Al ejecutar el programa ejecuta todo sin errore y muestra "Injection completed!", pero al cerrar el MessageBox que invoco el la aplicación a la que inyecto esta se me cierra también. Creo que se debe al calculo del tamaño de la función a inyectar, quizás dependiendo de un compilador pueda variar el resultado. Saludos y gracias.
|
|
« Última modificación: 7 Abril 2016, 12:58 pm por Kaxperday »
|
En línea
|
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.
|
|
|
fary
|
¿GetTargetThreadIDFromProcName?
¿Podrías poner el código completo e indicar que compilador estas usando?
saludos.
|
|
« Última modificación: 7 Abril 2016, 11:21 am por fary »
|
En línea
|
Un byte a la izquierda.
|
|
|
Kaxperday
Desconectado
Mensajes: 702
The man in the Middle
|
¿GetTargetThreadIDFromProcName?
¿Podrías poner el código completo e indicar que compilador estas usando?
saludos.
Hola fary, gracias por la respuesta. GetTargetThreadIDFromProcName es GetPIDFromProcName que lo cambié el nombre para que fuera más sencillo, eso ha sido un fallo de edición, es simplemente una función que devuelve el PID de un proceso que le pasas como argumento. Es GetPIDFromProcName vamos XD. El caso es el compilador y que no se como usar el debugger para pillar las direcciones de las funciones y en qué puede ayudarme a pesar de que he estado buscando sobre ello. Uso visual studio 2013 (v120). El compilador es derivado de g++ es propio de VS. Calculo el tamaño de la función con delimitandola con otra función static, pero ese método inestable para calcular el tamaño de la función dependiendo del compilador. Es probable que el mismo código funcione en codeblocks sin problemas. Pero en caso de ser eso lo que falle, ¿como puedo arreglarlo?, ¿dónde debería de inspeccionar?. Seguiré probando más adelante con la versión release y otros compiladores, pero tengo que hacerlo con el de VS. Un saludo. Edito: Buenas acabo de probar el código en codeblocks y funciona sin problemas, codeblocks usa g++ y para C gcc si no mal recuerdo. Luego no es problema del código, es del compilador.
|
|
« Última modificación: 7 Abril 2016, 13:00 pm por Kaxperday »
|
En línea
|
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.
|
|
|
fary
|
Me alegro de que hallas podido solucionar el problema.
En este caso podrías haber mirado lo que sucedia abriendo el ejecutable en cuestion en el que se va a inyectar el código con OllyDbg y poniendo en BP en la API MessageBoxA. Al inyectar el código se te pararía el programa y podrías ver donde esta el error.
saludos.
|
|
|
En línea
|
Un byte a la izquierda.
|
|
|
Kaxperday
Desconectado
Mensajes: 702
The man in the Middle
|
Bueno solucionado todavía no está, aunque si he confirmado que el problema tiene que ver con el compilador como suponía, luego el código está bien.
Ahora, creo que se puede solucionar de las siguientes maneras:
- Cargando el código a inyectar ya compilado en una variable e inyectar desde ella (no me acaba de gustar, pero ahí esta).
- Cambiando de compilador, el compilador de visual studio creo que ofusca el código y es por eso que falla, con otro funcionaría. Pero aún así no se podrian usar crypters ni nada por el estilo con el ejecutable, ya que al acceder al código a inyectar si esta ofuscado no funcionaría (aunque dependería del crypter algunos si), y eso es buena **.
- Como tú dices abriendo el ejecutable con el ollydbg, pero si por cada vez que lo vuelvo a compilar o cada cambio que añado tengo que estar haciendo eso para que funcione y buscando las direcciones de memoria y tal, tampoco me parece un buen método, pero es lo que más me convence aunque ahora mismo no sabría como hacerlo.
El problema de la inyección de código es: ¿es compatible con crypters?.
Luego me pondré a mirar como va eso del ollydbg a ver si encuentro algo X"D
Saludos!.
|
|
|
En línea
|
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.
|
|
|
|
pinkiepie
Desconectado
Mensajes: 2
|
No se trata del compilador exactamente, sino de características del código compilado (el compilador añade cosas caprichosamente que se pueden desactivar/remover [?]). Deberías revisar las instrucciones de la función a inyectar mediante IDA o algún debugger. Lo más probable es que encuentres al menos un CALL a una dirección de memoria, situado posteriormente al MessageBoxA, "perteneciente" al 'inyector' y no a chrome.exe. La función a la que intenta llamar el thread corresponde a _RTC_CheckEsp (al menos en VS2015). Pertenece a un conjunto de funciones que agrega el compilador para reportar errores en run-time, y se encuentra dentro del mismo ejecutable compilado. Te recomiendo visitar este enlace para que conozcas con más detalle sobre lo que es RTC (Run-Time Error Checking) y cómo desactivarlo: https://msdn.microsoft.com/en-us/library/8wtf2dfz.aspx
|
|
|
En línea
|
|
|
|
burbu_1
Desconectado
Mensajes: 159
hamen gaoz
|
Culpar al compilador de que tu código falle me parece muy chulito...... ésos son códigos....... has probado a reservar memoria como hace él/ella????
|
|
|
En línea
|
|
|
|
fary
|
Culpar al compilador de que tu código falle me parece muy chulito......
ésos son códigos.......
has probado a reservar memoria como hace él/ella????
no entiendo tu post :s Lo más fácil y mejor es que suba el ejecutable que genera y lo revisamos desde un debugger... Saludos!!
|
|
|
En línea
|
Un byte a la izquierda.
|
|
|
pinkiepie
Desconectado
Mensajes: 2
|
Pues yo insisto en que el problema son las verificaciones run-time que agrega VS a las funciones. Quité Run-Time Error Checking en las opciones del proyecto, compilé el programa (con VS2015), y no hubieron más crashes. Función inyectada con RTC activado: 023C0000 55 PUSH EBP 023C0001 8BEC MOV EBP,ESP 023C0003 81EC DC000000 SUB ESP,0DC 023C0009 53 PUSH EBX 023C000A 56 PUSH ESI 023C000B 57 PUSH EDI 023C000C 8DBD 24FFFFFF LEA EDI,DWORD PTR SS:[EBP-DC] 023C0012 B9 37000000 MOV ECX,37 023C0017 B8 CCCCCCCC MOV EAX,CCCCCCCC 023C001C F3:AB REP STOS DWORD PTR ES:[EDI] 023C001E 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] 023C0021 8B08 MOV ECX,DWORD PTR DS:[EAX] 023C0023 894D F8 MOV DWORD PTR SS:[EBP-8],ECX 023C0026 8BF4 MOV ESI,ESP 023C0028 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] 023C002B 8B48 50 MOV ECX,DWORD PTR DS:[EAX+50] 023C002E 51 PUSH ECX 023C002F 8B55 08 MOV EDX,DWORD PTR SS:[EBP+8] 023C0032 83C2 36 ADD EDX,36 023C0035 52 PUSH EDX 023C0036 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] 023C0039 83C0 04 ADD EAX,4 023C003C 50 PUSH EAX 023C003D 6A 00 PUSH 0 023C003F FF55 F8 CALL DWORD PTR SS:[EBP-8] 023C0042 3BF4 CMP ESI,ESP 023C0044 E8 09E6FFFF CALL 023BE652 ; _RTC_CheckEsp 023C0049 8945 EC MOV DWORD PTR SS:[EBP-14],EAX 023C004C 8B45 EC MOV EAX,DWORD PTR SS:[EBP-14] 023C004F 8985 24FFFFFF MOV DWORD PTR SS:[EBP-DC],EAX 023C0055 33C0 XOR EAX,EAX 023C0057 5F POP EDI 023C0058 5E POP ESI 023C0059 5B POP EBX 023C005A 81C4 DC000000 ADD ESP,0DC 023C0060 3BEC CMP EBP,ESP 023C0062 E8 EBE5FFFF CALL 023BE652 ; _RTC_CheckEsp 023C0067 8BE5 MOV ESP,EBP 023C0069 5D POP EBP 023C006A C3 RETN
Función inyectada sin RTC: 023A0000 55 PUSH EBP 023A0001 8BEC MOV EBP,ESP 023A0003 83EC 4C SUB ESP,4C 023A0006 53 PUSH EBX 023A0007 56 PUSH ESI 023A0008 57 PUSH EDI 023A0009 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] 023A000C 8B08 MOV ECX,DWORD PTR DS:[EAX] 023A000E 894D FC MOV DWORD PTR SS:[EBP-4],ECX 023A0011 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] 023A0014 8B48 50 MOV ECX,DWORD PTR DS:[EAX+50] 023A0017 51 PUSH ECX 023A0018 8B55 08 MOV EDX,DWORD PTR SS:[EBP+8] 023A001B 83C2 36 ADD EDX,36 023A001E 52 PUSH EDX 023A001F 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] 023A0022 83C0 04 ADD EAX,4 023A0025 50 PUSH EAX 023A0026 6A 00 PUSH 0 023A0028 FF55 FC CALL DWORD PTR SS:[EBP-4] 023A002B 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX 023A002E 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8] 023A0031 8945 B4 MOV DWORD PTR SS:[EBP-4C],EAX 023A0034 33C0 XOR EAX,EAX 023A0036 5F POP EDI 023A0037 5E POP ESI 023A0038 5B POP EBX 023A0039 8BE5 MOV ESP,EBP 023A003B 5D POP EBP 023A003C C3 RETN
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Ejecutar aplicación infectada = inyección en un proceso ??
Programación Visual Basic
|
FaiF (A¥åHøRå)
|
7
|
2,475
|
29 Junio 2006, 03:01 am
por Stewie.
|
|
|
¿Interceptar inyeccion de codigo en una aplicacion?
Programación Visual Basic
|
Magic_Key
|
7
|
6,525
|
18 Septiembre 2009, 21:19 pm
por Magic_Key
|
|
|
Inyeccion dll sin dll, by E0N. Problema: Edicion de Memoria. [Convertir a C#]
.NET (C#, VB.NET, ASP)
|
XSaMuXPH *-* Traigo uno encima! =D!
|
3
|
4,148
|
17 Septiembre 2009, 16:35 pm
por Atrum
|
|
|
sobre la inyección de dll en los offsets de una aplicación
Programación C/C++
|
while
|
9
|
3,704
|
28 Septiembre 2010, 02:59 am
por while
|
|
|
[Bug] CMD Se crashea con un codigo
Bugs y Exploits
|
sabeeee
|
7
|
4,492
|
19 Enero 2015, 16:25 pm
por sabeeee
|
|