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_listva_startva_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");
}
  1. 首先va_list定义了一个可变参数的指针。
  2. va_start函数传入,可变参数指针和最后一个固定参数,传出引用可变参数指针。
  3. 输出可变参数指针地址。
  4. 清空可变参数指针内存空间。

0x02 逆向分析C++可变参数原理

将上面的代码用VC6编译出来后进行调试分析。

找到特征。

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

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

接着按F7跟入test函数。

通过对汇编代码的分析,我大概知道了va_start函数()为什么要将最后一个固定参数传入。因为他需要用最后一个固定参数在堆栈中进行偏移的计算,计算出可变参数的地址。

遍历该堆栈,当遍历到的值是入口点,说明可变参数已经遍历完成。

0x03 printf Hook实战

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

Pwn菜鸡学习小分队

欢迎加入探讨 逆向知识和PWN

C++逆向 可变参数Hook的更多相关文章

  1. C可变参数的函数

    我们实现一个简单的printf函数(可变参数) #include <stdio.h> #include <stdarg.h> void myprintf(const char ...

  2. c#编程基础之函数可变参数

    可变参数:int sum (params int[] values)int sum (string name,params int[] values) 注意:params参数必须是形参表中的最后一个参 ...

  3. C语言的可变参数在Linux(Ubuntu)与Windows下注意点

    基本上C语言的可变参数原理在不同平台和不同编译器下基本类似(通过函数入栈,从右向左,从高位到低位地址),不过部分实现会有所不同:在使用中需要注意的是: va_list 为char 类型指针,部分调用如 ...

  4. 可变参数列表与printf()函数的实现

    问题 当我们刚开始学习C语言的时候,就接触到printf()函数,可是当时"道行"不深或许不够细心留意,又或者我们理所当然地认为库函数规定这样就是这样,没有发现这个函数与普通的函数 ...

  5. C#与Java对比学习:数据类型、集合类、栈与队列、迭达、可变参数、枚举

    数据类型: C#:String与StringBuilder Java:String与StringBuffer 第一个不习惯是string的第一个字母必须大写了. 第二个不习惯是int得写成Intege ...

  6. params可变参数

    class Program { // params可变参数 //将实参列表中跟可变参数数组类型一致的元素都当做数组的元素去处理. //params可变参数必须是形参列表中的最后一个元素. static ...

  7. java高新技术-可变参数与OverLoad相关面试题分析

    可变参数 可变参数的特点: 只能出现在参数列表的最后: ...位于变量类型和变量名之间,前后有无空格都可以: 调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法中以数组的形式访问可变参数 ...

  8. C和指针 第七章 可变参数

    可变参数列表是通过stdarg.h内的宏来实现的: 类型 va_list 三个宏: va_start va_arg va_end 我们可以声明一个va_list变量,与这三个宏配合使用. 可变参数必须 ...

  9. java可变参数

    Java1.5增加了新特性:可变参数:适用于参数个数不确定,类型确定的情况,java把可变参数当做数组处理.注意:可变参数必须位于最后一项.当可变参数个数多余一个时,必将有一个不是最后一项,所以只支持 ...

随机推荐

  1. python+pytest接口自动化(11)-测试函数、测试类/测试方法的封装

    前言 在python+pytest 接口自动化系列中,我们之前的文章基本都没有将代码进行封装,但实际编写自动化测试脚本中,我们都需要将测试代码进行封装,才能被测试框架识别执行. 例如单个接口的请求代码 ...

  2. C#中的类型转换-自定义隐式转换和显式转换

    目录 前言 基础知识 示例代码 实际应用 问题 答案 报错 用户定义的转换必须是转换成封闭类型,或者从封闭类型转换 参考 其他 应用和设计 读音 参考 前言 有时我们会遇到这么一种情况:在json数据 ...

  3. Linux 下通过ping判断机器有没有外网。(不用root)

    背景: 想实现一个判断当前系统有没有外网的方法,想到了两种思路: 1)实现一个ICMP协议.但是这个需要root权限才能运行.可以参考:https://www.cnblogs.com/xcywt/p/ ...

  4. List 操作add 报错

    操作List报java.lang.UnsupportedOperationException 2018.03.12 16:52:01字数 230阅读 1683 问题描述 今天在项目中调用List的ad ...

  5. zookeeper的通知机制

    一.znode Zookeeper维护一个类似文件系统的数据结构.简单来说,有点类似windows中注册表的结构,有名称,有树节点,有Key(键)/Value(值)对的关系,可以看做一个树形结构的数据 ...

  6. 写出Hibernate中核心接口/类的名称,并描述他们各自的责任?

    Hibernate的核心接口一共有5个,分别为:Session.SessionFactory.Transaction.Query和 Configuration.这5个核心接口在任何开发中都会用到.通过 ...

  7. Spring 配置文件 ?

    Spring 配置文件是个 XML 文件,这个文件包含了类信息,描述了如何配置它们,以及如何相互调用.

  8. JVM学习思考

    毕业以来技术上一直没有太大进步,仔细一想可能是没有做技术分享,我喜欢把学习总结记录在印象笔记中,那么理解的是对是错也就没人能评判一下.为了技术进步,接下来将陆续把一些学习总结迁移到博客园中,欢迎大家多 ...

  9. 数据仓库(5)数仓Kimball与Inmon架构的对比

    数据仓库主要有四种架构,Kimball的DW/BI架构.独立数据集市架构.辐射状企业信息工厂Inmon架构.混合Inmon与Kimball架构.不过不管是那种架构,基本上都会使用到维度建模. < ...

  10. solr集群搭建,zookeeper集群管理

    1. 第一步 把solrhome中的配置文件上传到zookeeper集群.使用zookeeper的客户端上传. 客户端命令位置:/root/solr-4.10.3/example/scripts/cl ...