首页
社区
课程
招聘
[讨论][重载大法好]发个这2天搞的小玩意的说 就是那个重载dll 顺带求教各位大神怎么学习逆向QAQ
发表于: 2014-5-28 14:21 12920

[讨论][重载大法好]发个这2天搞的小玩意的说 就是那个重载dll 顺带求教各位大神怎么学习逆向QAQ

2014-5-28 14:21
12920
首先声明咱不玩DOTA类游戏的说 (咱是前/伪wow饭/wow剧情饭  总觉得这类游戏有点那啥?非引起战争...dota饭别打我 掩面逃.....)
唔 这个就是看了前几天的那个帖子后想到的 本来想用来试试某游戏  结果好像是自己不给力(貌似有调用/堆栈检测  重载后进程直接奔溃......)所以就发上来啦
感谢lidagogo大指出的一个疏忽造成的错误的说......

顺带求各位大大怎么学习逆向的说  单条x86汇编指令都看的懂  它们加一起咱就不认识它们了  在没有符号文件的情况下看OD/WINDBG就是两眼一抹黑....就算有符号文件也能看API的调用什么的....函数内部各种瞎  求教各位大牛逆向应该看那些书  怎么入门才行的说

顺带想到个ring3下hook GetThreadContext的想法 : 吧ZwGetContextThread  mov eax,0x87  (服务号)改成jmp  在自己的函数里吧pContext->flag和 除了CONTEXT_DEBUG_REG位为0其他位为1的数 做 位与 操作  然后给eax赋值服务号 跳回 mov ebx,kifastsystemcall(是ebx么?忘了.......) 的地方

BOOL SetProtect()
{
  //char s[1024] = {0};
  
  ULONG i = 0;
  

  NTSTATUS status;
  PSYSTEM_PROCESSES pSysProcess;
  PSYSTEM_THREADS pSysThread;
  DWORD retlen,truelen;
  PVOID buf,pbuf;

  ThreadInfo hThread[1024] = {0};
  BOOL Ret,IsBreak;
  DWORD MayId = GetCurrentThreadId();
  DWORD old;

  NtResumeThread MyResThread = (NtResumeThread)GetProcAddress(GetModuleHandle(L"ntdll.dll"),"NtResumeThread");
  NtSuspendThread MySusThread = (NtSuspendThread)GetProcAddress(GetModuleHandle(L"ntdll.dll"),"NtSuspendThread");
  MyGetContext = (NtGetContextThread)GetProcAddress(GetModuleHandle(L"ntdll.dll"),"NtGetContextThread");
  MySetContext = (NtSetContextThread)GetProcAddress(GetModuleHandle(L"ntdll.dll"),"NtSetContextThread");
  NTQUERYSYSTEMINFORMATION NtQSIM = (NTQUERYSYSTEMINFORMATION)GetProcAddress(GetModuleHandle(L"ntdll.dll"),"ZwQuerySystemInformation");

  if(MyResThread == NULL || MySusThread == NULL || MyGetContext == NULL || MySetContext == NULL || NtQSIM == NULL)
    return FALSE;

  status = NtQSIM(SystemProcessInformation,NULL,0,&retlen);
  pbuf = VirtualAlloc(NULL,retlen,MEM_COMMIT,PAGE_READWRITE);
  if(pbuf == NULL)
    return FALSE;

  truelen = retlen;
  status= NtQSIM(SystemProcessInformation,pbuf,truelen,&retlen);
  buf=pbuf;
  IsBreak = FALSE;
  
  do 
  {
    pSysProcess=(PSYSTEM_PROCESSES)buf;
    if(pSysProcess->ProcessId == GetCurrentProcessId())
    {
      pSysThread=pSysProcess->Threads;
      for ( i=0;i<pSysProcess->ThreadCount;i++)
      {
        if((DWORD)pSysThread->ClientID.UniqueThread != MayId)
        {
          hThread[i].ThreadStarAddr = (DWORD)pSysThread->StartAddress;
          hThread[i].hThread = OpenThread(THREAD_ALL_ACCESS,FALSE,(DWORD)pSysThread->ClientID.UniqueThread);
          MySusThread(hThread[i].hThread,NULL);
          
        }
        pSysThread++;
        
      }
      IsBreak = TRUE;
    }
    

    if (pSysProcess->NextEntryDelta==0 || IsBreak)
    {
      break;
    }
    buf = (PVOID)((DWORD)buf + pSysProcess->NextEntryDelta);
  } while (1);
  
  VirtualFree(pbuf,truelen,NULL);

  if(CopyModule())
  {
    HookKiDispatch();
    VirtualProtect((PVOID)ModuleBase,ModuleSize-1,PAGE_READWRITE,&old);     //如果是PAGE_NOACCESS的话  读这段内存不也会触发异常?CRC怎么办?
    //SetMemProtect();      //有些模块没有text节区?
    
    for(ULONG j=0;j<=i;j++)
    {
      CONTEXT ct;
      ct.ContextFlags = CONTEXT_ALL;
      NTSTATUS status = MyGetContext(hThread[j].hThread,&ct);
      if(NT_SUCCESS(status))
      {
        if(ct.Eip >= ModuleBase && ct.Eip <= ModuleBase+ModuleSize)
        {
          ct.Eip = ct.Eip + JmpOffset;
          status = MySetContext(hThread[j].hThread,&ct);
        }
        
      }
      
      
    }
  
    
    ZeroMemory(NewModuleBase,1024);                       //防MZ暴力搜索←_←
    RtlCopyMemory(NewModuleBase,"NewTraget",sizeof("NewTraget"));      //给自己留个记号←_←
    //OutputDebugStringA("内存拷贝和保护设置成功!");
    Ret = TRUE;
    
  }
  else
  {
    
    Ret = FALSE;
  }

  
  for(ULONG j=0;j <= i;j++)
  {

    MyResThread(hThread[j].hThread,NULL);
    CloseHandle(hThread[j].hThread);
  }
  
  return Ret;
}


ps:代码各种抄 请各位大牛不要建议的说 代码也写的比较乱........
ps2:代码中删掉了一些私货  不过应该不影响主要功能......
ps3:吐槽下VS2010娘生成的代码好大......只能丢度娘网盘共享了
ps4:静态链接的MFC DLL生成的文件比易语言的还大.....下次谁说易语言生成的文件大可以拿这个打脸了23333
ps5:最后抱怨下该死的扫yellow打x  良心大大的的大数字网盘不能分享了....

http://pan.baidu.com/s/1ntJmDpZ  下载地址.....

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (25)
雪    币: 68
活跃值: (190)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
我不是大 不过还是顶你下
稍微看了下 真够乱的
搞不懂为什么用Nt的函数 直接用上层函数不好吗 就算游戏HOOK了 你Nt系列的 还是在他上面 就像DXF 还是被它HOOK了 它
为什么设置了SEH回调 还要HOOK 搞不懂
为什么不PAGE_NOACCESS 这样又跑到原始模块了 你SEH白建立了
我是VS2008没编译过 也没测试
这块我还真没弄过 改天也试试 看好玩不
2014-5-28 14:59
0
雪    币: 74
活跃值: (248)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
唔 设置了PAGE_READWRITE啊 不能执行  所以一执行就会跳到异常分发了  我用od跟过 eip确实是到了新的内存里了  如果设PAGE_NOACCESS的话 不就变成 CRC扫到也会触发异常?也许咱理解错了
设置VEH是刚开始写的时候搞的  后来发现有些进程没有进VEH就挂了  所以改为hook kiuser  但VEH这就懒得去掉了  以后用到的时候也能看看= =b   用NT系列么......DXF的话我用pc hunter看了下 RING3下并没有hook nt系列函数的样子.....大部分都是iat hook kernel32里的
2014-5-28 15:52
0
雪    币: 68
活跃值: (190)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
PAGE_NOACCESS 听他们讲 捕获后 先把内存属性恢复 然后 执行个单步 然后再设置回去吧
DXF都2年没看过了 不知道什么情况呵呵
这个重载 我没弄过的 貌似好好玩的样子
2014-5-28 16:08
0
雪    币: 74
活跃值: (248)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
这个倒给了我一个关于hook的想法.......唔  重载的话 那个不需要单步 只是捕获在旧模块里的eip然后转到新内存上 所以只要旧模块无法执行就可以了.....话说dxf啊  昨天天杀的在win7 64上用object hook了  而且不重启电脑无法恢复......
2014-5-28 16:12
0
雪    币: 68
活跃值: (190)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
CRC访问需要老模块属性切换回去吧 不然他没法读了
直接给新模块 新模块你不补丁吗 修改代码 不然重载不是没意义了
2014-5-28 16:15
0
雪    币: 74
活跃值: (248)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
所以我是设置成PAGE_READWRITE    这里只是重载嘛 用来对抗crc   想要怎么hook就按老的 hook地址再加上新模块和老模块之间的偏移做就就好了嘛   这个原来的思路是对某war3平台的  咱想拿来做别的......就是删掉的那些私货= =b   
dxf的话 好像有堆栈检测  重载后直接崩了......
2014-5-28 16:20
0
雪    币: 68
活跃值: (190)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
恩 这个思路是蛮不错的 有空可以研究下 有点意思
2014-5-28 16:24
0
雪    币: 74
活跃值: (248)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
可惜咱技术有限  无法发扬光大了..........
2014-5-28 16:29
0
雪    币: 952
活跃值: (1821)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
虚函数。。。。。怎么解决。。。。
2014-5-28 16:45
0
雪    币: 74
活跃值: (248)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
这个咱没能力解决   按照原帖V大的说法  虚表指针编译好后都存在在.data段  只要遍历这个data段然后再处理就好了
而且虚函数也是在模块内的吧.......只要eip指向就会抛出异常  新模块是按旧模块在运行时拷贝的   所以虚表不需要处理?
2014-5-28 16:49
0
雪    币: 68
活跃值: (190)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
不是只处理代码吗 PAGE_NOACCESS 为什么要处理虚函数呢
刚试了下 把代码段PAGE_NOACCESS 都不用暂停线程
就直接到了 自己的内存里 只要处理异常就可以了
我测试的是MFC程序 堆栈返回地址没处理 所以部分还会一直异常处理(消息循环)

可不可以复制2份 判断是哪个模块访问 一份用来CRC 一份用来执行
2014-5-28 17:05
0
雪    币: 74
活跃值: (248)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
   
可以看到   类函数也在模块内  所以...........
唔  这样判断起来貌似有点麻烦?效率也低  而且旧模块丢给CRC就好了么   
至于挂起线程么  大概是为了安全性吧  比如有个线程正好在对全局变量操作或调用函数   正好你复制了 那么线程需要的全局变量是新的  但你复制的是旧的....或者堆栈就不平衡了  大概是这样子吧
堆栈返回地址 刚开始是很多异常  等所有线程轮过一遍后就没多少了吧
上传的附件:
2014-5-28 17:21
0
雪    币: 68
活跃值: (190)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
堆栈返回地址没处理 最好在入口点就开始搞 这样就没返回地址要处理了
游戏是有很多死循环的 消息循环之类的
2014-5-28 17:27
0
雪    币: 74
活跃值: (248)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
不过入口点的话 对那些奇葩的壳就不行了吧话说看雪好冷清啊....
2014-5-28 17:33
0
雪    币: 9941
活跃值: (2143)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
16
VS的工程不会大
你可以把 .sdf 文件 与 Release  ipch 目录都删除  
压缩一下,20KB不到
2014-5-28 17:39
0
雪    币: 68
活跃值: (190)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
是够冷清的
2014-5-28 17:39
0
雪    币: 74
活跃值: (248)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
消息循环的话 第一次eip中标  进入新内存 然后调用下一层函数的时候返回地址就是镜像里的地址了  只要整个循环都异常一遍 应该就正常了
2014-5-28 17:45
0
雪    币: 74
活跃值: (248)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
有空了试试....话说巨硬果然是和硬盘厂家串通好了的
2014-5-28 17:48
0
雪    币: 265
活跃值: (84)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
好冷清好冷清,大牛都取赚钱钱啦
2014-5-30 09:48
0
雪    币: 414
活跃值: (987)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
21
性能比较...吃紧!!!!!!!!!
2014-5-30 19:17
0
雪    币: 74
活跃值: (248)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
←_←现在电脑动辄4核起步 就算是G1620之流性能也不差   而且就如原帖所说 只要第一次EIP中标 以后的栈返回地址都在新内存里了  所以性能方面应该大丈夫萌大奶
2014-5-30 21:03
0
雪    币: 7
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
能告诉有什么意义吗
2014-5-31 13:51
0
雪    币: 7
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
直接判断esp非game.dll的地址就好了
2014-5-31 14:05
0
雪    币: 74
活跃值: (248)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
如果其他模块调用的话 esp不在当前模块里的吧 话说咱本来是想做别的东西的←_←
2014-5-31 14:57
0
游客
登录 | 注册 方可回帖
返回
//