你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:杂志经典 / 编程语言
C++实现远程线程技术(二)
 

3 编程实现

//为了简化代码,下面程序中去掉了对出错处理的代码,实际应用中应考虑程序运行时可能的出错
#include "stdafx.h"
static PIMAGE_NT_HEADERS    nt_header;
#define IMAGESIZE (nt_header->OptionalHeader.SizeOfImage)
#define EXPORT_TABEL   (nt_header->OptionalHeader.DataDirectory[0].VirtualAddress)
#define RELOC_TABEL    (nt_header->OptionalHeader.DataDirectory[5].VirtualAddress)
static void RelocCode (PBYTE  Image, LPBYTE   InjectBase) // 完成代码的重定位
{    DWORD  Rva = 0, RvaCount = 0, RelocOffset=0;
WORD  *Offset = NULL;
     LPBYTE RelocTable = Image + RELOC_TABEL; //重定位表位置
PIMAGE_BASE_RELOCATION  basereloc= (PIMAGE_BASE_RELOCATION) RelocTable;
     RelocOffset= (DWORD)InjectBase -  nt_header ->OptionalHeader.ImageBase; //重定位表偏移
while(basereloc ->VirtualAddress != NULL)// 遍历重定位表,修正需要重定位的代码
{  Offset = (WORD*)(RelocTable + sizeof(IMAGE_BASE_RELOCATION));
      RvaCount = (basereloc ->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / 2;
      for(DWORD i=0; i<RvaCount; i++)
      {  Rva = Offset[i];
         if(( Rva & 0xf000) != 0x3000)      continue;//4位为03H表示需要修正
         Rva &= 0x0fff;//取出低12位,即重定位代码的相对虚拟地址
         Rva += basereloc ->VirtualAddress + (DWORD)Image;
         *(DWORD*)Rva += RelocOffset;//RVA加上修正量进行修正
       }
       RelocTable += basereloc ->SizeOfBlock;//指向下一页重定位信息处
       basereloc  = (PIMAGE_BASE_RELOCATION) RelocTable;
}
}
int LoadAPI(LPBYTE InjectBase)// 用于完成API函数的导入,参数为要插入代码处地址
{  PIMAGE_DOS_HEADER dos_h = (PIMAGE_DOS_HEADER) InjectBase;
   PIMAGE_NT_HEADERS nt_h = (PIMAGE_NT_HEADERS)(InjectBase + dos_h->e_lfanew);
   PIMAGE_IMPORT_DESCRIPTOR import_d = (PIMAGE_IMPORT_DESCRIPTOR)
       (InjectBase + nt_h->OptionalHeader.DataDirectory[1].VirtualAddress);
   for(  ; import_d->OriginalFirstThunk != 0; import_d++)//遍历导入表
   {     HMODULE hDll = LoadLibrary((LPCSTR)(InjectBase + import_d->Name));
           //上面能直接引用LoadLibrary是由于本地和远程进程中该函数地址都是相同的
         if(hDll == NULL)  return 0;
         PIMAGE_THUNK_DATA Origin = (PIMAGE_THUNK_DATA)(InjectBase +
import_d->OriginalFirstThunk);
         PIMAGE_THUNK_DATA First = (PIMAGE_THUNK_DATA)(InjectBase + import_d->FirstThunk);
         LPCSTR Name = NULL;
         PIMAGE_IMPORT_BY_NAME Import_name = NULL;
         for(; Origin->u1.Ordinal != 0; Origin++, First++)
         {   if(Origin->u1.Ordinal & IMAGE_ORDINAL_FLAG)
                   Name = (LPCSTR)IMAGE_ORDINAL(Origin->u1.Ordinal);
            else{  Import_name = (PIMAGE_IMPORT_BY_NAME)(InjectBase + 
(DWORD)( Origin->u1.AddressOfData));
                   Name = (LPCSTR)Import_name->Name; }
            First->u1.Function = (DWORD * )GetProcAddress(hDll, Name);
        //上面能直接引用GetProcAddress是由于本地和远程进程中该函数地址都是相同的
            if(First->u1.Function == NULL)  return 0;
         }
     }
    return 1;
}
  推荐精品文章

·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录
·2023年10月目录
·2023年9月目录 
·2023年8月目录 

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089