首页
论坛
专栏
课程

[原创]用C代实现远程线程(无dll)

2008-4-11 00:24 15907

[原创]用C代实现远程线程(无dll)

2008-4-11 00:24
15907
近日拜读了罗云彬先生写的远程线程代码后,心里佩服不已。
就想自己也写一个练练,由于自己水平不高,在写的过程中遇到不小困难,小小的百来行代码写我一个多星期。
现在把代码贴出来请各位前来“挑挑刺”。
编译平台:Windows 2003,Visual c++ 2003。编译的时候要用Release,否则代码运行不了。下面符上代码,和符件(所有代码和程序)。
#include "win32.h"
#define MAX_SIZE 19

char * szData[MAX_SIZE] = {
  "Kernel32.dll",
  "LoadLibraryA",
  "GetProcAddress",
  "GetModuleHandleA",
  "GDI32.dll",
  "User32.dll",
  "DestroyWindow",
  "PostQuitMessage",
  "DefWindowProcA",
  "LoadCursorA",
  "LoadIconA",
  "RegisterClassExA",
  "CreateWindowExA",
  "ShowWindow",
  "UpdateWindow",
  "GetMessageA",
  "TranslateMessage",
  "DispatchMessageA",
  "MessageBoxA"
};

int _WinMain(LPARAM);
ATOM _MyRegisterClass(HINSTANCE, LPARAM);
BOOL _InitInstance(HINSTANCE hInstance, int, LPARAM);
LRESULT __stdcall _WndProc(HWND, UINT, WPARAM, LPARAM);
DWORD WINAPI RemoteThread(LPARAM);

#pragma code_seg("CodeSeg2")

//导入函数地址表
__declspec(allocate("CodeSeg2"))DWORD lpLoadLibrary=0;  
__declspec(allocate("CodeSeg2"))DWORD lpGetProcAddress=0;
__declspec(allocate("CodeSeg2"))DWORD lpGetModuleHandle=0;
__declspec(allocate("CodeSeg2"))DWORD lpDestroyWindow=0;
__declspec(allocate("CodeSeg2"))DWORD lpPostQuitMessage=0;
__declspec(allocate("CodeSeg2"))DWORD lpDefWindowProc=0;
__declspec(allocate("CodeSeg2"))DWORD lpLoadCursor=0;
__declspec(allocate("CodeSeg2"))DWORD lpLoadIcon=0;
__declspec(allocate("CodeSeg2"))DWORD lpRegisterClassEx=0;
__declspec(allocate("CodeSeg2"))DWORD lpCreateWindowEx=0;
__declspec(allocate("CodeSeg2"))DWORD lpShowWindow=0;
__declspec(allocate("CodeSeg2"))DWORD lpUpdateWindow=0;
__declspec(allocate("CodeSeg2"))DWORD lpGetMessage=0;
__declspec(allocate("CodeSeg2"))DWORD lpTranslateMessage=0;
__declspec(allocate("CodeSeg2"))DWORD lpDispatchMessage=0;
__declspec(allocate("CodeSeg2"))DWORD lpMessageBox=0;

//全局变量:
__declspec(allocate("CodeSeg2"))DWORD _hInstance=0;      
__declspec(allocate("CodeSeg2"))DWORD _hWinMain=0;
//字符串表
__declspec(allocate("CodeSeg2"))char _szClassName[]="RemoteClass";
__declspec(allocate("CodeSeg2"))char _szCaptionMain[]="RemoteWindow";

LRESULT __stdcall _WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  DWORD lOffset;

  __asm{
    push edx
    call lab
    lab:
    pop edx
    sub edx, lab
    mov lOffset, edx
    pop edx
  }

  switch (message) 
  {
  case WM_DESTROY:
    ReloCationForLP(lpPostQuitMessage,lOffset)(0);
    break;
  default:
    return ReloCationForLP(lpDefWindowProc,lOffset)(hWnd, message, wParam, lParam);
  }

  return 0;
}

DWORD WINAPI RemoteThread(LPARAM lParam){
  ReloCationForDWORD(_hInstance,lParam) = DWORD(ReloCationForLP(lpGetModuleHandle,lParam)(NULL));
  _WinMain(lParam);
  return 0;
}
int _WinMain(LPARAM lParam){
  HINSTANCE hInstance = HINSTANCE(ReloCationForDWORD(_hInstance, lParam));
  MSG Message;

  _MyRegisterClass(hInstance, lParam);
  
  if(!_InitInstance(hInstance, SW_SHOWNORMAL, lParam))
    return FALSE;

  while(ReloCationForLP(lpGetMessage, lParam)(&Message,0,0,0)){
    ReloCationForLP(lpTranslateMessage, lParam)(&Message);
    ReloCationForLP(lpDispatchMessage, lParam)(&Message);
  }

  return int(Message.wParam);
}
ATOM _MyRegisterClass(HINSTANCE hInstance, LPARAM lParam)
{
  WNDCLASSEX wcex;
  wcex.cbSize = sizeof(WNDCLASSEX); 

  wcex.style      = CS_HREDRAW | CS_VREDRAW;
  wcex.lpfnWndProc  = WNDPROC(DWORD(&_WndProc) + DWORD(lParam));
  wcex.cbClsExtra    = 0;
  wcex.cbWndExtra    = 0;
  wcex.hInstance    = hInstance;
  wcex.hIcon      = ReloCationForLP(lpLoadIcon, lParam)(NULL, IDC_ICON);
  wcex.hCursor    = ReloCationForLP(lpLoadCursor, lParam)(NULL, IDC_ARROW);
  wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
  wcex.lpszMenuName  = 0;
  wcex.lpszClassName  = ReloCataonForTCHAR(_szClassName, lParam);
  wcex.hIconSm    = ReloCationForLP(lpLoadIcon, lParam)(NULL, IDC_ICON);
  return ReloCationForLP(lpRegisterClassEx,lParam)(&wcex);
}

BOOL _InitInstance(HINSTANCE hInstance, int nCmdShow, LPARAM lParam)
{
  HWND hWnd;
   hWnd = ReloCationForLP(lpCreateWindowEx,lParam)(WS_EX_CLIENTEDGE, ReloCataonForTCHAR(_szClassName, lParam), 
    ReloCataonForTCHAR(_szCaptionMain, lParam), WS_OVERLAPPEDWINDOW,
      100, 100, 600, 400, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   ReloCationForLP(lpShowWindow,lParam)(hWnd, nCmdShow);
   ReloCationForLP(lpUpdateWindow,lParam)(hWnd);

   return TRUE;
}
#pragma code_seg()

// win32.cpp : 定义应用程序的入口点。
//
int __stdcall Enter()
{
  DWORD dwProcessID;
  HANDLE hProcess, hThread;
  LPVOID lpBaseAddress;  //远程线程基址
  LPTHREAD_START_ROUTINE lpStartAddress;  //远程线程入口地址
  HMODULE hModule = 0;

  DWORD hMod = DWORD(GetModuleHandle(NULL));
  PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMod;
    PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)(hMod + pDosHdr->e_lfanew );
    PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION( pNtHdr );
  for (unsigned i = 0;i < pNtHdr->FileHeader.NumberOfSections;i++, pSection++ )
    if (!strncmp("CodeSeg2",(char *)(pSection->Name),8)) break;

  LPDWORD lpData = LPDWORD(&lpLoadLibrary);
  for(int i = 0; i < MAX_SIZE; i ++){
    *lpData = (DWORD)GetProcAddress(hModule, szData[i]);
    if (*lpData) lpData ++;
    else hModule = GetModuleHandle(szData[i]);
  }
  GetWindowThreadProcessId(FindWindow(TEXT("Progman"),TEXT("Program Manager")), &dwProcessID);
  hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, dwProcessID);
  if(hProcess){
    lpBaseAddress = VirtualAllocEx(hProcess, NULL, pSection->SizeOfRawData, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    if(lpBaseAddress){
      lpStartAddress = LPTHREAD_START_ROUTINE(DWORD(lpBaseAddress) + DWORD(RemoteThread) - DWORD(&lpLoadLibrary));
      WriteProcessMemory(hProcess, lpBaseAddress, LPVOID(&lpLoadLibrary), pSection->SizeOfRawData, NULL);
      hThread = CreateRemoteThread(hProcess, NULL, 0, lpStartAddress, LPVOID(DWORD(lpBaseAddress) - DWORD(&lpLoadLibrary)), 0, NULL);
//      WaitForSingleObject(hThread,INFINITE);
//      VirtualFreeEx(hProcess, lpBaseAddress, 0, MEM_RELEASE);
      CloseHandle(hThread);
    }
    CloseHandle(hProcess);
  }
  else{
    MessageBox(NULL, TEXT("无法打开进程!"), TEXT("错误"), 0);
  }

  return 0;
}

[公告]安全测试和项目外包请将项目需求发到看雪企服平台:https://qifu.kanxue.com

上传的附件:
最新回复 (24)
救世猪 1 2008-4-11 08:05
2
0
沙发……
学习………………
救世猪 1 2008-4-11 08:40
3
0
#define ReloCationForLP(x1,x2) (__##x1(ReloCationForDWORD(x1,x2)))

楼主,这是什么意思????
没看懂~~~
ReloCationForDWORD(x1,x2)本来就是取得的x1的重定位后的值
又把它变成__x1(Address)????
(基础太差………… )
combojiang 26 2008-4-11 08:57
4
0
写得不错,学习
sudami 25 2008-4-11 10:18
5
0
远程线程本来就可以不要dll.

《WINDOWS核心编程》有完整的code和详细的说明分析。

很古老的东西了啊
小五穆 1 2008-4-11 10:23
6
0
比如说:ReloCationForLP(lpUpdateWindow,lParam)(hWnd)
ReloCationForDWORD(x1,x2)取得x1的重定位后的值
最后变成__lpUpdateWindow(Address)。

"__pUpdateWindow"在头文件有定义:
typedef BOOL (__stdcall *__lpUpdateWindow)(
  HWND
  );
小五穆 1 2008-4-11 10:26
7
0
老罗的代码我也是今年才看到,也是看了他的代码才知道远程线程这个东西,现在只是写来练练。
海风月影 17 2008-4-11 11:50
8
0
写得很不错~~

给个小建议:
把重定位的代码剥离出来,重新写一个函数
  __asm{
    push edx
    call lab
    lab:
    pop edx
    sub edx, lab
    mov lOffset, edx
    pop edx
  }

上面这段代码不要写在某个过程里面,单独拿出来
__declspec(naked) DWORD GetDelta()
{
__asm
{
	call next
next:
	pop eax
	sub eax,offset next
	ret
}
}

然后要获取delta的时候,调用一下GetDelta就可以了

比如:
DWORD lOffset = GetDelta();

内嵌进去如果寄存器用不好会出现可爱的错误

To sudami:远程线程是古老的技术,但楼主这篇文章的价值在于高效地维护这段远程线程代码,试想用汇编去实现复杂的远程线程功能,要写多少代码,维护起来有多麻烦

如果我是版主,肯定给精华了
shoooo 16 2008-4-11 11:53
9
0
fengyue说好就是好
ccfer 13 2008-4-11 12:09
10
0
支持fengyue申请版主
sunbinjin 1 2008-4-11 13:52
11
0
等于把所有的代码都复制到远程进程去了,小的话还可以,如果远程做的事非常多的话

还是DLL比较方面,也省心省力
yiyiguxing 1 2008-4-11 18:30
12
0
是不错!    虽然直接写DLL更有实效性
linyboy 2008-4-11 18:52
13
0
学习了几个VC的用法,不错
小五穆 1 2008-4-12 12:12
14
0
谢谢海风月影的建议。多谢版主给加精
靴子 2008-4-12 14:18
15
0
不错 学习了.
hfyy 2 2008-4-12 18:02
16
0
我觉得还是用汇编简单
frozenrain 2008-4-12 20:12
17
0
一下下来 卡巴就叫个不停
petnt 12 2008-4-12 20:16
18
0
很强大,学习了
小五穆 1 2008-4-12 23:21
19
0
放心不是病毒的。
ysoni 2008-4-14 09:52
20
0
很强很暴力。
whtyy 1 2008-4-14 10:57
21
0
赞个,思路不错

不过这样写代码比用汇编都累,而且你也不能完全确定编译器产生的其他部分的代码是可重定位的
紫色的魚 2008-4-26 09:13
22
0
在网吧试了一下,蓝屏了。XP SP2
ertyui 2008-5-26 19:00
23
0
第一次听说,学习了
jjgogo 2008-5-27 08:05
24
0
学习学习!!!
pcstone 2011-8-2 15:55
25
0
好东西,正要使用
游客
登录 | 注册 方可回帖
返回