C++逆向 可变参数Hook
C++逆向 可变参数Hook
0x00 前言:
我们在做逆向分析的时候,经常会需要去Hook一个程序的日志输出函数。
而这种日志输出函数一般参数都不确定,这就会引起一个问题。我们如何知道参数个数?如何知道他有哪些参数呢?
0x01 C++可变参数:
可变参数简介
在C++中,可变参数的函数定义可以写成如下格式。用...来声明可变参数。
void test(int a,int b,...)
{
//Code...
}
在调用可变参数的函数时,可以在后面不断添加参数,例如。
test(1,2,3,4,5,"hello","test",6);
可变参数代码实战
那么回归正题,test函数里如何知道它传进来的后面所有参数个数呢?
这就需要用到stdarg.h头文件中的几个关键字了va_list、va_start、va_end。
#include <stdio.h>
#include <stdarg.h>
void test(int a,int b,...)
{
va_list arg_ptr;//定义可变参数指针
va_start(arg_ptr,b); //b为最后一个固定参数
printf("Address = %p",arg_ptr);//将arg_ptr的地址进行输出。
va_end(arg_ptr); //清空可变参数指针
}
int main(int argc,char *argv[])
{
test(1,2,3,4,5,"hello","test,6");
}
- 首先va_list定义了一个可变参数的指针。
- va_start函数传入,可变参数指针和最后一个固定参数,传出引用可变参数指针。
- 输出可变参数指针地址。
- 清空可变参数指针内存空间。
0x02 逆向分析C++可变参数原理
将上面的代码用VC6编译出来后进行调试分析。

找到特征。

在汇编代码中,定位到main函数。

接着在汇编处call va_arg.401005处下一个断点。可以看到他将参数一个个push到了堆栈中。

接着按F7跟入test函数。
通过对汇编代码的分析,我大概知道了va_start函数()为什么要将最后一个固定参数传入。因为他需要用最后一个固定参数在堆栈中进行偏移的计算,计算出可变参数的地址。
遍历该堆栈,当遍历到的值是入口点,说明可变参数已经遍历完成。


0x03 printf Hook实战
这里我随便选了一个系统的可变参数函数,printf可以将格式化后的字符串进行输出,符合我们可变参数函数的要求。

Pwn菜鸡学习小分队
欢迎加入探讨 逆向知识和PWN

C++逆向 可变参数Hook的更多相关文章
- C可变参数的函数
我们实现一个简单的printf函数(可变参数) #include <stdio.h> #include <stdarg.h> void myprintf(const char ...
- c#编程基础之函数可变参数
可变参数:int sum (params int[] values)int sum (string name,params int[] values) 注意:params参数必须是形参表中的最后一个参 ...
- C语言的可变参数在Linux(Ubuntu)与Windows下注意点
基本上C语言的可变参数原理在不同平台和不同编译器下基本类似(通过函数入栈,从右向左,从高位到低位地址),不过部分实现会有所不同:在使用中需要注意的是: va_list 为char 类型指针,部分调用如 ...
- 可变参数列表与printf()函数的实现
问题 当我们刚开始学习C语言的时候,就接触到printf()函数,可是当时"道行"不深或许不够细心留意,又或者我们理所当然地认为库函数规定这样就是这样,没有发现这个函数与普通的函数 ...
- C#与Java对比学习:数据类型、集合类、栈与队列、迭达、可变参数、枚举
数据类型: C#:String与StringBuilder Java:String与StringBuffer 第一个不习惯是string的第一个字母必须大写了. 第二个不习惯是int得写成Intege ...
- params可变参数
class Program { // params可变参数 //将实参列表中跟可变参数数组类型一致的元素都当做数组的元素去处理. //params可变参数必须是形参列表中的最后一个元素. static ...
- java高新技术-可变参数与OverLoad相关面试题分析
可变参数 可变参数的特点: 只能出现在参数列表的最后: ...位于变量类型和变量名之间,前后有无空格都可以: 调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法中以数组的形式访问可变参数 ...
- C和指针 第七章 可变参数
可变参数列表是通过stdarg.h内的宏来实现的: 类型 va_list 三个宏: va_start va_arg va_end 我们可以声明一个va_list变量,与这三个宏配合使用. 可变参数必须 ...
- java可变参数
Java1.5增加了新特性:可变参数:适用于参数个数不确定,类型确定的情况,java把可变参数当做数组处理.注意:可变参数必须位于最后一项.当可变参数个数多余一个时,必将有一个不是最后一项,所以只支持 ...
随机推荐
- webdriver原理及操作
webdriver原理: 1. WebDriver 启动目标浏览器,并绑定到指定端口.该启动的浏览器实例,做为 webdriver 的 remote server. 2. Client 端通过 Com ...
- POI Excel索引是从0还是1开始??
this.workbook.getSheetAt(1).getFirstRowNum() // == 0 this.workbook.getSheetAt(1).getLastRowNum() // ...
- Eclipse创建Spring XML配置文件插件
引用:https://www.cnblogs.com/lideqiang/p/9067219.html 第一步:在 Eclipse Marketplace仓库中,搜索sts 第二步:安装Spring ...
- spring boot 自动装配的原理
参考: https://blog.csdn.net/Dongguabai/article/details/80865599.如有侵权,请联系本人删除! 入口: import org.springfra ...
- mysql常见命令参数(一)
1.mysql命令常用参数 1.--auto-rehash (tab键自动补全,表名及表字段) # mysql -u root --auto-rehash # vim my.cnf [mysql] a ...
- three模型高亮外发光效果
页面效果如下: vue3+three完整代码如下: <template> </template> <script setup> import * as THREE ...
- SringBoot之yaml语法
------------恢复内容开始------------ SpringBoot之yaml语法 1.配置文件 官方配置文档太多了,根本记不住! 怎么办呐-->了解原理 SpringBoot使用 ...
- -> 在c语言中是什么意思?
->在C语言中称为间接引用运算符,是二目运算符,优先级同成员运算符".".用法:p->a,其中p是指向一个结构体的指针,a是这个结构体类型的一个成员.表达式p-> ...
- STM32 中的 assert_param 函数
在学STM32的时候函数assert_param出现的几率非常大,上网搜索一下,网上一般解释断言机制,做为程序开发调试阶段时使用. 断言机制函数assert_param我们在分析库函数的时候,几乎每一 ...
- 微信小程序要求HTTPS,如何选择SSL证书?
为了保护小程序应用安全,微信官方的需求文档要求,每个微信小程序必须事先设置一个通讯域名,并通过HTTPS请求进行网络通信,不满足条件的域名和协议无法请求.因此开发者应先准备好配置好HTTPS证书的域名 ...