.Net,C#程序的HOOK
.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相关推荐
- Linux上监控应用程序启动 (hook execve系统调用)
对于linux x86-64平台,hook普通的系统调用是一件比较简单的事情,可以看hook系统调用完整实例讲解.但是对于execve.fork.clone等这些系统调用的hook却并没那么简单了. ...
- android hook 程序,Android hook框架之Xposed插件开发
上一篇讲了Android hook框架Cydia,这一篇是Android hook的另一个框架Xposed,Xposed是一款广泛应用于安卓领域的开源框架. 其原理是Xposed框架主要通过替换/sy ...
- android hook截取其他程序的按钮事件_Hook技术
概述 Hook,英文直译是"钩子"的意思.在程序中将其理解为"劫持"可能会更好理解,我们可以通过hook技术来劫持某个对象,从而控制它与其他对象的交互. Hoo ...
- HOOK API(二)—— HOOK自己程序的 MessageBox
0x00 前言 以下将给出一个简单的例子,作为HOOK API的入门.这里是HOOK 自己程序的MessageBox,即将自己程序对MessageBox API的调用重定向到自己实现的API中,在自己 ...
- [C++]键盘钩子程序
实现适时监视键盘,并将按键信息保存在TXT文件中的程序 Windows系统是建立在事件驱动的机制上的,说穿了就是整个系统都是通过消息的传递来实现的.而钩子是Windows系统中非常重要的系统接口,用它 ...
- Android免Root环境下Hook框架Legend原理分析
0x1 应用场景 现如今,免Root环境下的逆向分析已经成为一种潮流! 在2015年之前的iOS软件逆向工程领域,要想对iOS平台上的软件进行逆向工程分析,越狱iOS设备与安装Cydia是必须的!几乎 ...
- C# Hook原理及EasyHook简易教程
前言 在说C# Hook之前,我们先来说说什么是Hook技术.相信大家都接触过外挂,不管是修改游戏客户端的也好,盗取密码的也罢,它们都是如何实现的呢? 实际上,Windows平台是基于事件驱动机制的, ...
- 《Android安全技术揭秘与防范》—第8章8.5节Hook检测/修复
本节书摘来自异步社区<Android安全技术揭秘与防范>一书中的第8章8.5节Hook检测/修复,作者周圣韬,更多章节内容可以访问云栖社区"异步社区"公众号查看. 8. ...
- Windows下Hook API技术小结 (转)
1.基本概念 钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的.当消息到达后,在目标窗口处理函数之前 ...
最新文章
- C++ STL: 分配器allocators 源码分析
- python100行代码程序-100行python代码,轻松完成贪吃蛇小游戏
- 心路历程(一)-自学java两个月心得
- android选项菜单源代码,Android应用程序----UI界面控件(菜单menu)
- (转)常用正则表达式
- 关于反射调用方法的一个log
- 构建虚拟工控环境系列 - 罗克韦尔虚拟PLC
- 以编程方式在ASP.NET MVC中使用多个HTML Select控件
- python中最难的是什么_传说中Python最难理解的点|看这完篇就够了
- PTES标准中的渗透测试阶段(要点)
- 论文解读:FASPell: A Fast, Adaptable, Simple, Powerful Chinese Spell Checker Based On DAE-Decoder Paradig
- 微信视频号头像怎么换?怎么设置?必看!5个思路帮你快速敲定头像
- 【YOLO】目标检测第三步——用Pascal voc 2012 数据集训练YOLO网络
- The stash entry is kept in case you need it again.
- 被诸葛亮的光环掩盖起来的三国英雄
- 【Vue】如何请求后台数据
- 在deepin20.6上运行ros和far planner
- promise 实现分批请求
- SOLIDWORKS: Mold Design SOLIDWORKS:模具设计 Lynda课程中文字幕
- N3-PEG-MAL,Azdio-PEG-Maleimide,一种点击化学PEG试剂
热门文章
- java-swing-事件监听-MouseEvent-右键弹出菜单
- 2017CS231n笔记7.训练神经网络(下)
- Android默认启动器原理
- Python爬虫(二)正则表达式
- [转]Web应用防火墙WAF详解
- 计算机 校级研究生学术会议,通知 | 【研究生评奖评优】关于做好浙江大学2017-2018学年计算机学院研究生学年小结及评奖评优工作的通知...
- python拟合反比例函数_Python 数据处理(八)—— 应用函数
- 微信小程序报错 errcode: 40029, errmsg: “invalid code 针对狮子鱼
- 【feign】OpenFeign设置header的5种方式
- selenium 自动打开Chrome浏览器且重复使用已打开的Chrome实例