♂hook♂学习笔记~(持续更新)

news/2025/1/1 8:46:21/文章来源:https://www.cnblogs.com/T0fV404/p/18638928

主要是从攻防世界中的easyhook中学习,感觉好神奇.

参考了以下博客:

攻防世界逆向高手题之EASYHOOK-CSDN博客

RE套路/从EASYHOOK学inline hook - c10udlnk - 博客园

先贴源码:

 sub_401370(aPleaseInputFla);scanf("%31s", input_flag);if ( strlen(input_flag) == 19 ){sub_401220();		//未知名函数,一开始当然不会注意v4 = CreateFileA(FileName, 0x40000000u, 0, 0, 2u, 0x80u, 0);		//创建文件函数WriteFile(v4, input_flag, 19u, &NumberOfBytesWritten, 0);		//写入函数,这些系统函数通常不是重点,如果影响理解代码的话直接查API即可,  WriteFile(句柄, 写入字符串, 写入字节, 指向写入直接的指针, 0)sub_401240(input_flag, &NumberOfBytesWritten);if ( NumberOfBytesWritten == 1 )	//判断函数sub_401370(aRightFlagIsYou);elsesub_401370(aWrong);system(Command);result = 0;}else{sub_401370(aWrong);system(Command);result = 0;}return result;
}

然后要注意sub_401220():

int sub_401220()
{HMODULE v0; // eaxDWORD v2; // eaxv2 = GetCurrentProcessId();			//系统函数,获取进程ID,就是当前程序的IDhProcess = OpenProcess(0x1F0FFFu, 0, v2);		//系统函数,返回现有进程对象的句柄。v0 = LoadLibraryA(LibFileName);			//系统函数,将指定的可执行模块映射到调用进程的地址空间,这里LibFileName双击跟踪存入的是kernel32.dll模块,就是导入了它*(_DWORD *)WriteFile_0 = GetProcAddress(v0, ProcName);		//系统函数,返回指定的导出动态链接库(DLL)函数的地址。 ProcName存放的是WriteFile函数名,也就是导入WriteFile函数。lpAddress = *(LPVOID *)WriteFile_0;	//获取WriteFile函数地址if ( !*(_DWORD *)WriteFile_0 )		//无用函数,因为kernel32.dll模块的WriteFile函数一定存在return sub_401370(&unk_40A044);	//sub_401370函数类型puts函数,是通过主函数分析得到的,&unk_40A044处的字符串是获取原API入口地址出错,不用管他。unk_40C9B4 = *(_DWORD *)lpAddress;		//这里获取WriteFile函数的地址*((_BYTE *)&unk_40C9B4 + 4) = *((_BYTE *)lpAddress + 4);		//这里地址后四位也保持一样,不知道有什么用aHook1 = 0xE9;		//这里连同第二句是我犯下的第二个错误:这里转十六进制不是E9,是JMP的机器码指令,而不一开始并没有机器码的相关知识。aHook2 = (char *)sub_401080 - (char *)lpAddress - 5;		//这里是一个偏移地址,而且还是满足HOOK的连续地址。之所以这样写是因为汇编语言JMP address被编译后会变成机器指令码,E9  偏移地址,偏移地址=目标地址-当前地址-5(jmp和其后四位地址共占5个字节)。所以前面直接用E9,这里直接用偏移地址就省去编译生成机器码那一步。这也是HOOK的原型。return sub_4010D0();		返回一个函数,继续跟踪,因为前面并没有什么修改程序的行为
}

主要看下面,可以看到这里搞了jmp,而且注意aHook1和aHook2(这里是我修改过的名字)是连续的,也就是说,可以看成jmp sub_401080.

接下来看sub_4010D0():

BOOL sub_4010D0()
{DWORD v1; // [esp+4h] [ebp-8h] BYREFDWORD flOldProtect; // [esp+8h] [ebp-4h] BYREFv1 = 0;VirtualProtectEx(hProcess, lpAddress, 5u, 4u, &flOldProtect);WriteProcessMemory(hProcess, lpAddress, &aHook1, 5u, 0);//修改return VirtualProtectEx(hProcess, lpAddress, 5u, flOldProtect, &v1);
}
//VirtualProtectEx(进程,修改地址,修改区域大小,[修改其中权限,1,2,4对应执行,写,读],一个保存修改前权限的变量 ),所以这三行作用是对lpAddress所存储的地址处进行了5字节的权限修改操作,先改成读写再往此处写入以前面E9 偏移量地址处的5个字节(即上面的跳板指令),最后恢复权限,完成修改。

这就是hook,劫持程序流.

那么现在WriteFile被改写成了jmp也就是跳到sub_401080,我们看看它:

int __stdcall sub_401080(HANDLE hFile,LPCVOID lpBuffer,DWORD nNumberOfBytesToWrite,LPDWORD lpNumberOfBytesWritten,LPOVERLAPPED lpOverlapped)
{int v5; // ebxv5 = sub_401000(lpBuffer, nNumberOfBytesToWrite); //加密函数sub_401140(); //这个是把WriteFile恢复的函数WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);if ( v5 )*lpNumberOfBytesWritten = 1;return 0;
}

sub_401000:

int __cdecl sub_401000(int input_flag, int _19)
{char i; // alchar v3; // blchar v4; // clint v5; // eaxfor ( i = 0; i < _19; ++i ){if ( i == 18 ){*(_BYTE *)(input_flag + 18) ^= 19u;       // 这里犯下第五个错误,写脚本时这种单独的if语句应该直接在外面单独成行,不然就要多写几个elif语句了,界面就会很乱!}else{if ( i % 2 )v3 = *(_BYTE *)(i + input_flag) - i;elsev3 = *(_BYTE *)(i + input_flag + 2);*(_BYTE *)(i + input_flag) = i ^ v3;}}v4 = 0;if ( _19 <= 0 )                               // 不会小于等于,所以不会在这里返回return 1;v5 = 0;while ( aAjygkfm[v5] == *(_BYTE *)(v5 + input_flag) )		//这里犯下第四个错误,前面的加密逻辑中我们没有可以参照的字符串,因为flag是推出来的,而真正的字符串在后面,所以逆向逻辑时首先要找到非输入的字符串才行!这里双击跟踪 aAjygkfm等于ajygkFm.\x7f_~-SV{8mLn{v5 = ++v4;if ( v4 >= _19 )return 1;}return 0;
}

写脚本,可得flag为:"-lag{Ho0k_w1th_Fun}"

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/860872.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于PY打包文件的解包的记录(转载为主)

由于这个很玄学,加之很多人的文章太老了,所以我打算写一篇文档. 首先得会打包,才能解包.故贴上打包文章:Python pyinstaller打包exe最完整教程_python exe-CSDN博客 我没细看,稍微看了下原理,不知道对不对.1 简介 python提供了多种方法用于将普通的*.py程序文件编译成exe文件(…

C++异常处理机制学习(持续更新)

具体的异常要回去学中断这些,我打算到时候再细致研究,故而这里只是粗浅地讨论C++的异常处理机制.(其实没太看懂原理和应用的关系,以后还要深入研究)首先我们要探究一下seh异常处理机制,从与其相关的数据结构讲起.TIB结构 TIB (Thread Infoimation Block, 线程信息块)是保存线…

PYTHON语言学习笔记(基础语法篇)

Python学习笔记 序言 主要是以小甲鱼的视频为主,https://space.bilibili.com/314076440 一些特性 多次调用方法是从左到右.而参数是函数则先执行参数. 一行如果要多个赋值,用;隔开 input().split() IO 看我放在另一个地方的文档.<D:\Document\md\PYTHON\IO.md> 数据类型 …

2024-11-28《关于mybatis创建的mapper映射路径不对导致的系列报错》

关于mybatis创建的mapper映射路径不对导致的系列报错今天在写mybatis项目的时候,使用注解发现无法使用别名,添加ResultMap的时候直接报错显示无法解析。 经过百度了好久也是成功的发现了问题的所在,就是这个:这个路径创建的时候我以为创建的是分级目录,实际上创建成为了co…

2024-11-29《axios获取不到response返回的响应的解决方法》

axios获取不到response返回的响应的解决方法今天在用mybatis+vue+axios写登录界面的时候,发现用户名还有密码的数据都能够传输到servlet里,但是当servlet对html界面进行相应的时候,axios却收不到消息,经过长时间的排查后也没有发现问题,终于在今晚的百度下发现了结果,上原…

如何解决宝塔面板无法登录的问题?

您好,当您遇到宝塔面板无法登录的问题时,可以按照以下步骤进行排查和解决:确认初始密码:如果您从未修改过宝塔面板的登录密码,默认情况下,宝塔面板的初始密码与服务器的初始密码相同。您可以尝试使用服务器的初始密码进行登录。如果您不确定服务器的初始密码,可以在云服…

如何解决网站默认80端口无法访问的问题?

您好,当您遇到网站默认80端口无法访问的问题时,可以按照以下步骤进行排查和解决:确认域名解析:首先,检查域名是否正确解析到服务器的IP地址。您可以通过在线DNS查询工具(如(网址))来验证域名解析是否正确。如果解析有问题,请联系域名注册商进行修正。检查服务器状态:登…

请问如何解决宝塔面板无法登录的问题?

您好,当您遇到宝塔面板无法登录的问题时,可以按照以下步骤进行排查和解决,确保能够顺利访问并管理您的服务器:确认初始密码:如果您从未修改过宝塔面板的登录密码,默认情况下,宝塔面板的初始密码与服务器的初始密码相同。您可以尝试使用服务器的初始密码进行登录。如果您…

网站频繁出现500错误 - 云服务器性能问题

关于您提到的网站经常报500错误并且服务器卡死的问题,这是一个比较复杂的情况,涉及到多个方面。为了帮助您彻底解决这个问题,我们需要从以下几个角度进行分析和排查: 一、服务器资源监控 首先,当网站出现500错误时,服务器资源(CPU、内存、磁盘I/O等)是否处于高位占用状…

网站后台打开出错 - 虚拟主机/数据库问题

一、检查PHP版本兼容性 首先,您提到有时登录时会遇到错误提示,而有时又能正常访问。这种情况可能与PHP版本有关。不同的PHP版本对某些函数或库的支持程度不同,如果您的网站程序依赖于特定版本的PHP特性,当切换到不兼容的版本时,可能会导致功能异常。 建议您尝试切换PHP版本…

2024-11-11《VsCode运行时输出日志》

VsCode运行C#时终端输出日志最近在使用vscode运行C#项目的时候,终端总会先输出一些无关的日志信息才会输出运行结果,搜索解决后发现是终端输出了日志信息,首先咱们看一下他输出的信息。这是我的代码: using System; using System.Collections.Generic; using System.Lin…

2024-10-31《c#学习》

今天进行了C#的初步学习,主要了解了C#的相关知识:目录基础语法 数据类型值类型 引用类型 动态(Dynamic)类型 字符串类型 指针类型类型转换 变量 常量 运算符 判断 循环 封装 基础语法首先是在C#里的基础语法,大致与C++还有Java类似,可以说是二者的结合体,基本的Hello Worl…