Почитал статейку решил переписать сорец на С++ инжет не проходи в чем проблема никак не могу понять Код (Text): #define nil NULL LPVOID InjectMemory(HANDLE Process,LPVOID Memory,DWORD Size); DWORD WINAPI RemoteThread(LPVOID RemoteInfo); void RemoteThreadEnd(); typedef int(*MsgBox)(HWND,LPCSTR,LPCSTR,UINT); typedef void(*ExTh)(int); typedef HMODULE(*LoadLib)(LPCTSTR); typedef FARPROC(*GetProc)(HMODULE,LPCSTR); struct TRemoteInfo { /* type TRemoteInfo = record LoadLibrary: function(lpLibFileName: PChar): HMODULE; stdcall; GetProcAddress: function(hModule: HMODULE; lpProcName: LPCSTR): FARPROC; stdcall; Kernel32 : array[0..16] of Char; User32 : array[0..16] of Char; MessageBoxA : array[0..16] of Char; nExitThread : array[0..16] of Char; Text : array[0..16] of Char; Title : array[0..16] of Char; end; */ char Kernel32[16]; char User32[16]; char MessageBoxA[16]; char nExitThread[16]; char Text[16]; char Title[16]; LoadLib l; GetProc g; }; int main() { //var TRemoteInfo RemoteInfo; LPVOID pInfo, CodeAdr; DWORD TID; HANDLE Process; STARTUPINFO StartInfo; PROCESS_INFORMATION ProcInfo; //begin //Запускаем процесс ZeroMemory(&StartInfo, sizeof(STARTUPINFO)); StartInfo.cb= sizeof(STARTUPINFO); CreateProcess(nil, "notepad.exe", nil, nil, false, 0, nil, nil, &StartInfo, &ProcInfo); Process = ProcInfo.hProcess; //Заполняем структуру передаваемую внедряемому коду lstrcpy(RemoteInfo.User32, "user32.dll"); lstrcpy(RemoteInfo.Kernel32, "kernel32.dll"); lstrcpy(RemoteInfo.MessageBoxA, "MessageBoxA"); lstrcpy(RemoteInfo.nExitThread, "ExitThread"); lstrcpy(RemoteInfo.Text, "Hello World!"); lstrcpy(RemoteInfo.Title, "Injected MessageBox"); //получаем адреса используемых API //@RemoteInfo.LoadLibrary := GetProcAddress(GetModuleHandle('kernel32.dll'), // 'LoadLibraryA'); //@RemoteInfo.GetProcAddress := GetProcAddress(GetModuleHandle('kernel32.dll'), // 'GetProcAddress'); //копируем в процесс структуру с данными LoadLib l=(LoadLib)GetProcAddress(GetModuleHandle("kernel32.dll"),"LoadLibraryA"); GetProc g=(GetProc)GetProcAddress(GetModuleHandle("kernel32.dll"),"GetProcAddress"); pInfo= InjectMemory(Process, &RemoteInfo, sizeof(TRemoteInfo)); //копируем в процесс внедряемый код CodeAdr= InjectMemory(Process,&RemoteThread,(DWORD)(&RemoteThreadEnd) - (DWORD)(&RemoteThread)); //запускаем внедренный код CreateRemoteThread(Process, nil, 0, (PTHREAD_START_ROUTINE)CodeAdr, pInfo, 0, &TID); getch(); } void RemoteThreadEnd() { } LPVOID InjectMemory(HANDLE Process,LPVOID Memory,DWORD Size) { //var DWORD BytesWritten; //begin LPVOID Result=VirtualAllocEx(Process,NULL,Size,MEM_RESERVE,PAGE_EXECUTE_READWRITE); WriteProcessMemory(Process,Result,Memory,Size,&BytesWritten); return Result; //end; } DWORD WINAPI RemoteThread(LPVOID RemoteInfo) { //var TRemoteInfo Info; MsgBox mBox=(MsgBox)Info.g(Info.l(Info.User32),"MessageBoxA"); ExTh exTh=(ExTh)Info.g(Info.l(Info.Kernel32),"ExitThread"); mBox(0,Info.Text,Info.Title,0); exTh(0); return 1; } При запуске процес блокнота напрочь вылетает
mark4545 CodeAdr= InjectMemory(Process,&RemoteThread,(DWORD)(&RemoteThreadEnd) - (DWORD)(&RemoteThread)); Например, в оригинале СТАТЬИ > Секреты Win32 > Перехват API функций в Windows NT (часть 2). Методы внедрения кода. /16.05.05/ подпрограмма RemoteThreadEnd расположена после подпрограммы RemoteThread.
так нашел недочет еще один Изменил вот это Код (Text): MsgBox mBox=(MsgBox)Info.g(Info.l(Info.User32),"MessageBoxA"); ExTh exTh=(ExTh)Info.g(Info.l(Info.Kernel32),"ExitThread"); на вот это Код (Text): MsgBox mBox=(MsgBox)Info.g(Info.l(Info.User32),Info.MessageBoxA); ExTh exTh=(ExTh)Info.g(Info.l(Info.Kernel32),Info.nExitThread);
mark4545 Так какая разница прототип функции то описан. При чем тут прототип? Хочешь почуствовать разницу - посмотри в отладчике, что помещается в качестве трнтьего аргумента подпрограммы InjectMemory когда подпрограмма RemoteThreadEnd расположена после подпрограммы RemoteThread и наоборот.
mark4545 поставил RemoteThreadEnd после RemoteThread И это правильно. все равно те же пироги Продолжим. Где заполнение struct TRemoteInfo.l и struct TRemoteInfo.g. Т.е. где соответствие оригинальному Код (Text): ... @RemoteInfo.LoadLibrary := GetProcAddress(GetModuleHandle('kernel32.dll'), 'LoadLibraryA'); @RemoteInfo.GetProcAddress := GetProcAddress(GetModuleHandle('kernel32.dll'), 'GetProcAddress'); ... И наконец самое главное - инжектируемый поток. В нем ты завел переменную TRemoteInfo Info (в оригинале ее нет) она ни чем не инициализирована, а ты используешь ее поля - Info.g, Info.l, Info.User32, Info.MessageBoxA, Info.Kernel32 и Info.nExitThread. В оригинале используется параметр (не зря же заполняли структуру и инжектировали ее до кода) созданного потока.
да да это я ипсравил изменил это Код (Text): LoadLib l=(LoadLib)GetProcAddress(GetModuleHandle("kernel32.dll"),"LoadLibraryA"); GetProc g=(GetProc)GetProcAddress(GetModuleHandle("kernel32.dll"),"GetProcAddress"); на это Код (Text): RemoteInfo.l=(LoadLib)GetProcAddress(GetModuleHandle("kernel32.dll"),"LoadLibraryA"); RemoteInfo.g=(GetProc)GetProcAddress(GetModuleHandle("kernel32.dll"),"GetProcAddress");
тогда думаю ошибка где то : Код (Text): DWORD WINAPI RemoteThread(LPVOID RemoteInfo) { //var TRemoteInfo Info; MsgBox mBox=(MsgBox)Info.g(Info.l(Info.User32),"MessageBoxA"); ExTh exTh=(ExTh)Info.g(Info.l(Info.Kernel32),"ExitThread"); mBox(0,Info.Text,Info.Title,0); exTh(0); return 1; } TRemoteInfo - где заполняеться? А то вижу что только используеться и все.
в main lstrcpy(); Говорю же это попытка прееписать исходник ms-rem для самообучения. Его сорец пашет нормально.