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把可变参数当做数组处理.注意:可变参数必须位于最后一项.当可变参数个数多余一个时,必将有一个不是最后一项,所以只支持 ...
随机推荐
- 老徐和阿珍的故事:CAP是什么?超级爱放P吗?
人物背景: 老徐,男,本名徐福贵,从事Java相关研发工作多年,职场老油条,摸鱼小能手,虽然岁数不大但长的比较着急,人称老徐.据说之前炒某币败光了所有家产,甚至现在还有欠债. 阿珍,女,本名陈家珍,刚 ...
- Prometheus自定义监控告警项-3
prometheus 编写告警规则 将自定义的告警规则写到独立的文件中,prometheus.yml中引用如下: rule_files: - "rules/*.yml" [root ...
- python3 爬虫3--异常处理
本文学习内容来自:https://germey.gitbooks.io/python3webspider/content/ urllib库中有URLError类,request模块产生的错误都可以通过 ...
- struts2学习一:hello struts2及struts2环境配置中遇到的问题
17年下半年的时候简单学了下strus2,好吧,现在已经全忘了,idea也是刚开始用,本来想按教程写个hello struts2,结果,出了以下系列问题. pre:step1-5是我按照百度的教程搭的 ...
- innodb和myisam
在Mysql数据库中,常用的引擎主要就是2个:Innodb和MyIASM.这篇文章将主要介绍这两个引擎,以及该如何去选择引擎,最后在提一下这2种引擎所使用的数据结构是什么. 首先介绍一下Innodb引 ...
- docker-compose安装和使用
安装:https://my.oschina.net/thinwonton/blog/2985886 docker-compose和Dockerfile结合使用,创建django项目和postgres数 ...
- SpringAOP+RabbitMQ+WebSocket实战
背景 最近公司的客户要求,分配给员工的任务除了有微信通知外,还希望PC端的网页也能实时收到通知.管理员分配任务是在我们的系统A,而员工接受任务是在系统B.两个系统都是现在已投入使用的系统. 技术选型 ...
- Atomic 的实现原理
1.直接操作内存,使用Unsafe 这个类 2.使用 getIntVolatile(var1, var2) 获取线程间共享的变量 3.采用CAS的尝试机制(核心所在),代码如下: public fin ...
- ctfhub web 前置技能(请求方式、302跳转、Cookie)
第一题:请求方式 打开环境分析题目发现当前请求方式为GET 查看源码发现需要将请求方式改为CTFHUB就可以 使用bp抓包 发送到repeater模块修改请求方式 即可得到flag 第二题:302跳转 ...
- (stm32学习总结)—对寄存器的理解
芯片里面有什么 我们看到的 STM32 芯片是已经封装好的成品,主要由内核和片上外设组成.若与电脑类比,内核与外设就如同电脑上的 CPU 与主板.内存.显卡.硬盘的关系.STM32F103 采用的是 ...