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把可变参数当做数组处理.注意:可变参数必须位于最后一项.当可变参数个数多余一个时,必将有一个不是最后一项,所以只支持 ...
随机推荐
- SolidWorks在一个零件中设置不同的尺寸版本
问题 比如想设置一系列螺丝的长度,一个一个建零件非常麻烦,希望在一个零件中设置不同的长度尺寸版本 解决 比如想设置不同的拉伸长度,右键拉伸>配置特征 可以生成新配置,设置不同的D1参数,即可生成 ...
- 几种常用的MOS管参数、应用电路及区别:IRF540N、IRF9540N、IRF9540
1. IRF540N,N沟道,100V,33A,44mΩ@10V 栅极(Gate-G,也叫做门极),源极(Source-S), 漏极(Drain-D) 漏源电压(Vdss) 100V 连续漏极电流(I ...
- 12.9 supper
Super super的注意事项 super可以用来在子类中访问父类的public属性或方法,super只能出现在子类中. super()调用的是父类的默认无参构造,super(参数)可以调用父类的有 ...
- Springmvc入门基础(二) ---架构详解
1.框架结构图 架构流程文字说明 用户发送请求至前端控制器DispatcherServlet DispatcherServlet收到请求调用HandlerMapping处理器映射器. 处理器映射器根据 ...
- Java 中的 TreeMap 是采用什么树实现的?
Java 中的 TreeMap 是使用红黑树实现的.
- 说出 5 个 JDK 1.8 引入的新特性?
Java 8 在 Java 历史上是一个开创新的版本,下面 JDK 8 中 5 个主要的特性: Lambda 表达式,允许像对象一样传递匿名函数 Stream API,充分利用现代多核 CPU,可以写 ...
- 是否可以从一个静态(static)方法内部发出对非静态 (non-static)方法的调用?
不可以,静态方法只能访问静态成员,因为非静态方法的调用要先创建对象,在 调用静态方法时可能对象并没有被初始化.
- Linux编译安装软件常见问题及排查
1.配置cmake参数时提示: The C compiler identification is unknown. The CXX compiler identification is unknown ...
- 3.3V转5V原理图
- 怎样用JavaScript和HTML5 Canvas绘制图表
原文:https://code.tutsplus.com/zh-...原作:John Negoita翻译:Stypstive 在这篇教程中,我将展示用JavaScript和canvas作为手段,在饼状 ...