.Net,C#程序的HOOK

最近有个需求,就是要在一个软件里面获取一个编号

当时我想这还不是so easy,找到那个框的句柄,发个消息就能拿到,百度一下

https://www.cnblogs.com/lujin49/p/4796502.html

几行代码不就搞定了,哈哈哈~

SPYXX掏出来,我擦!!!根本没有控件句柄!!!

怎么搞?再后来看了下软件,mmp是dotnet写的。。。。。。。

好吧,这招不行的话,我掏出CheatEngine就是一顿乱搜,好吧,找不到基址。。。

嘿嘿,.net写的软件不就是源码么,呵呵,掏出.net大杀器dnSpy,马上找到关键代码

private string xxx(SomeStruct ss)
{Config.CyclePressValue = 25;Config.TrgCycleTime = (DateTime.Now - this.TrgTime).TotalSeconds;...GC.Collect();GC.WaitForPendingFinalizers();return "";
}

SomeStruct那个结构体里面就有要找的那个数字,代码我修改了下,naked拿出来好像不太好。。。

这要是c写的就好办了,.net这种我以前还没搞过,好吧再百度找找有没有人整过这种类型的

欸,有了!!https://blog.csdn.net/xfgryujk/article/details/79053312

不过这只管hook到自己的代码,回不到原来的函数,而且还是clrcall类型的。。。

后来又搜了好多,基本没什么有用的信息,.net的hook资料是真的少~

好吧,那就自己来吧。既然JIT是运行时编译,那编译好的代码看看先吧,CE掏出一顿操作,CE还蛮强,.net的类和函数都能看到

找到上面的那个函数名称双击就能看到已经编译好的代码:

这里其实有个坑,等会说。。。

现在思路清晰了,俺们可以直接内存爆搜Opcode,找到JIT后的地址,然后直接hook这个地址

mov rax,我的代码地址jmp rax

直接写个dll,然后注入就完事了。。。

这里有个问题,VS写64位asm代码不支持__asm{}这种类型了,要么你换intel的编译器,要么你写个.asm文件再asm+c混合编译。

下面重点经验来了:!!!

vs里面Cpp文件下,要引用asm中的函数,声明一下

extern "C" void asmcode();

asm文件中要引用cpp的函数,要这样写

extrn RunMyCode : proc

这样可以完美互相引用对方的函数

.asm文件中代码

extrn RunMyCode : proc.codeasmcode procpush rbxpush rcxpush rdxpush rbppush rsipush rdipush r8push r9push r10push r11push r12push r13push r14push r15pushfq
//上面的代码保存现场,下面是运行hook后我们自己的代码,找到我们需要的那串数字push raxlea rcx,[rdx+170h]call RunMyCodepop rax
//恢复现场popfqpop r15pop r14pop r13pop r12pop r11pop r10pop r9pop r8pop rdipop rsipop rbppop rdxpop rcxpop rbx
//这里是被替换掉的原始代码,需要补上push rdipush rsipush rbppush rbxsub rsp,28hmov rsi,rcxmov rdi,rdx
//补完后可以跳回原来的函数地址mov rax,1234567812345678hjmp rax
asmcode endp
end

CPP文件大概代码


#include "pch.h"
#include <vector>using namespace std;
static BYTE m_Shared[100] = { 0 };extern "C" void RunMyCode(LPVOID pAddr)
{//HANDLE hMap = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, 0, L"MySharedMemory");//if (hMap == NULL)//{// hMap = ::CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 1024, L"MySharedMemory");//    LPVOID pBuffer = ::MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);//    ZeroMemory(pBuffer, 0x100);memcpy(m_Shared, pAddr, 10);//   ::UnmapViewOfFile(pBuffer);//   ::CloseHandle(hMap);//}
}extern "C" void asmcode();DWORD WINAPI InitHookThread(LPVOID dllMainThread)
{WaitForSingleObject(dllMainThread, INFINITE);CloseHandle(dllMainThread);std::vector<unsigned __int64> ResultArray;SearchMemory(GetCurrentProcess(), (char*)"57 56 55 53 48 83 EC 28 48 8B F1 48 8B FA C7 05 ?? ?? ?? ?? 19 00 00 00 E8 ?? ?? ?? ?? 48 8B C8 48 8B 56 50 E8 ?? ?? ?? ?? C4 E1 78 57 C0 C4 E1 FB 2A C0", 0x0, 0x7FFFFFFFFFFF, 10, ResultArray);if (ResultArray.size()>0){LPVOID paddr = (LPVOID)ResultArray.at(0);__int64 dwFunc = GetFunAddress((PUCHAR)asmcode);for (PUCHAR pBuf = (PUCHAR)dwFunc; pBuf < ((PUCHAR)dwFunc + 1024); ++pBuf){if (*(__int64*)pBuf == 0x1234567812345678){__int64 tmp = (__int64)paddr + 0xE;DWORD dOldProtect;VirtualProtect((LPVOID)dwFunc,0x100, PAGE_EXECUTE_READWRITE, &dOldProtect);memcpy(pBuf, &tmp, sizeof(tmp));break;}}BYTE jmpcode[] = { 0x48, 0xB8 , 0x78 , 0x56 , 0x34 , 0x12 , 0x78 , 0x56 , 0x34 , 0x12 , 0xFF , 0xE0 };memcpy(jmpcode + 2, &dwFunc, 8);memcpy(paddr, jmpcode, sizeof(jmpcode));}while (1){Sleep(3000);}return 0;
}BOOL APIENTRY DllMain(HMODULE hModule,DWORD  ul_reason_for_call,LPVOID lpReserved
)
{switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:{//DisableThreadLibraryCalls(hModule);HANDLE curThread;if (!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &curThread, SYNCHRONIZE, FALSE, 0))return FALSE;CloseHandle(CreateThread(NULL, 0, InitHookThread, curThread, 0, NULL));}break;case DLL_THREAD_ATTACH:case DLL_THREAD_DETACH:case DLL_PROCESS_DETACH:break;}return TRUE;
}

hook到那串数字后,本来打算用filemapping映射到内存来和自己的程序通信,后来省事直接在dll整了个static的内存,直接读dll的内存好了。

RunMyCode函数带一个参数,所以

lea rcx,[rdx+170h]  ->rcx取到那串数字的偏移地址,作为参数
    call RunMyCode

好,到这里注入后就OK成功了。。。

去现场一试,BOOM!!!其实到了反汇编这里,不BOOM才不正常。。。这就是上面说的坑!

后来调试发现,.net版本不一样,JIT后的OPCode显然会大大的不一样。。。包括结构体的偏移量,全都变~~

其实上面提到的那篇文章也说了,“hook .NET程序的难点在于.NET程序都是JIT临时编译的,函数的地址不确定。我翻了一下MSDN,发现可以用RuntimeMethodHandle的GetFunctionPointer获取编译后的函数地址,于是用C++/CLI调用.NET的反射和GetFunctionPointer就可以实现hook了”,但是整了那个clr问题好多,编译都编译不起来,只能这样了。。。

特此记录下hook .net遇到的坑~

.Net,C#程序的HOOK相关推荐

  1. Linux上监控应用程序启动 (hook execve系统调用)

    对于linux x86-64平台,hook普通的系统调用是一件比较简单的事情,可以看hook系统调用完整实例讲解.但是对于execve.fork.clone等这些系统调用的hook却并没那么简单了. ...

  2. android hook 程序,Android hook框架之Xposed插件开发

    上一篇讲了Android hook框架Cydia,这一篇是Android hook的另一个框架Xposed,Xposed是一款广泛应用于安卓领域的开源框架. 其原理是Xposed框架主要通过替换/sy ...

  3. android hook截取其他程序的按钮事件_Hook技术

    概述 Hook,英文直译是"钩子"的意思.在程序中将其理解为"劫持"可能会更好理解,我们可以通过hook技术来劫持某个对象,从而控制它与其他对象的交互. Hoo ...

  4. HOOK API(二)—— HOOK自己程序的 MessageBox

    0x00 前言 以下将给出一个简单的例子,作为HOOK API的入门.这里是HOOK 自己程序的MessageBox,即将自己程序对MessageBox API的调用重定向到自己实现的API中,在自己 ...

  5. [C++]键盘钩子程序

    实现适时监视键盘,并将按键信息保存在TXT文件中的程序 Windows系统是建立在事件驱动的机制上的,说穿了就是整个系统都是通过消息的传递来实现的.而钩子是Windows系统中非常重要的系统接口,用它 ...

  6. Android免Root环境下Hook框架Legend原理分析

    0x1 应用场景 现如今,免Root环境下的逆向分析已经成为一种潮流! 在2015年之前的iOS软件逆向工程领域,要想对iOS平台上的软件进行逆向工程分析,越狱iOS设备与安装Cydia是必须的!几乎 ...

  7. C# Hook原理及EasyHook简易教程

    前言 在说C# Hook之前,我们先来说说什么是Hook技术.相信大家都接触过外挂,不管是修改游戏客户端的也好,盗取密码的也罢,它们都是如何实现的呢? 实际上,Windows平台是基于事件驱动机制的, ...

  8. 《Android安全技术揭秘与防范》—第8章8.5节Hook检测/修复

    本节书摘来自异步社区<Android安全技术揭秘与防范>一书中的第8章8.5节Hook检测/修复,作者周圣韬,更多章节内容可以访问云栖社区"异步社区"公众号查看. 8. ...

  9. Windows下Hook API技术小结 (转)

    1.基本概念 钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的.当消息到达后,在目标窗口处理函数之前 ...

最新文章

  1. C++ STL: 分配器allocators 源码分析
  2. python100行代码程序-100行python代码,轻松完成贪吃蛇小游戏
  3. 心路历程(一)-自学java两个月心得
  4. android选项菜单源代码,Android应用程序----UI界面控件(菜单menu)
  5. (转)常用正则表达式
  6. 关于反射调用方法的一个log
  7. 构建虚拟工控环境系列 - 罗克韦尔虚拟PLC
  8. 以编程方式在ASP.NET MVC中使用多个HTML Select控件
  9. python中最难的是什么_传说中Python最难理解的点|看这完篇就够了
  10. PTES标准中的渗透测试阶段(要点)
  11. 论文解读:FASPell: A Fast, Adaptable, Simple, Powerful Chinese Spell Checker Based On DAE-Decoder Paradig
  12. 微信视频号头像怎么换?怎么设置?必看!5个思路帮你快速敲定头像
  13. 【YOLO】目标检测第三步——用Pascal voc 2012 数据集训练YOLO网络
  14. The stash entry is kept in case you need it again.
  15. 被诸葛亮的光环掩盖起来的三国英雄
  16. 【Vue】如何请求后台数据
  17. 在deepin20.6上运行ros和far planner
  18. promise 实现分批请求
  19. SOLIDWORKS: Mold Design SOLIDWORKS:模具设计 Lynda课程中文字幕
  20. N3-PEG-MAL,Azdio-PEG-Maleimide,一种点击化学PEG试剂

热门文章

  1. java-swing-事件监听-MouseEvent-右键弹出菜单
  2. 2017CS231n笔记7.训练神经网络(下)
  3. Android默认启动器原理
  4. Python爬虫(二)正则表达式
  5. [转]Web应用防火墙WAF详解
  6. 计算机 校级研究生学术会议,通知 | 【研究生评奖评优】关于做好浙江大学2017-2018学年计算机学院研究生学年小结及评奖评优工作的通知...
  7. python拟合反比例函数_Python 数据处理(八)—— 应用函数
  8. 微信小程序报错 errcode: 40029, errmsg: “invalid code 针对狮子鱼
  9. 【feign】OpenFeign设置header的5种方式
  10. selenium 自动打开Chrome浏览器且重复使用已打开的Chrome实例