巩固C语言(十)----指针数组 & 函数指针和指针函数
2016-04-18 21:28
615 查看
1 利用指针数组实现多个函数劫持技术
#include<stdio.h> #include<stdlib.h> #include<windows.h> #include"detours.h" #pragma comment(lib, "detours.lib") int newAdd(int a, int b) //static文件只能限制在本文件使用 { printf("+++++++\n"); return a + b; } int newMinis(int a, int b) { printf("-----------\n"); return a - b; } int newMulti(int a, int b) //函数名是一个常量地址 { printf("***********\n"); return a*b; } int newDel(int a, int b) { printf("///////////"); return a / b; } int add(int a, int b) //static文件只能限制在本文件使用 { return a + b; } int minis(int a, int b) { return a - b; } int multi(int a, int b) //函数名是一个常量地址 { return a*b; } int del(int a, int b) { return a / b; } static int(*OldFunction[4])(int, int) = { add, minis, multi, del }; //被劫持函数数组 int(*NewFunction[4])(int, int) = { newAdd, newMinis, newMulti, newDel }; //劫持函数数组 //开始拦截 void Hook() { DetourRestoreAfterWith(); //恢复原来的状态 DetourTransactionBegin(); //拦截开始 DetourUpdateThread(GetCurrentThread()); //刷新当前线程 //这里可以连续多次调用DetourAttach,表明Hook多个函数 for (int i = 0; i < 4; i++) DetourAttach((void**)&OldFunction[i], NewFunction[i]); //实现函数拦截, 如果想拦截多个指令,只需添加多个拦截函数即可 DetourTransactionCommit(); //拦截生效 } void main() //函数名实际上保存着这个函数的地址 { int(*p)(int a, int b) = add; //函数指针 printf("1 + 2 = %d\n", add(1, 2)); p = minis; printf("1 - 2 = %d\n", minis(1, 2)); Hook(); //开始劫持 int(*pp[4])(int a, int b) = { add, minis, multi, del }; //函数指针数组,注意函数的返货类型要一致 for (int i = 0; i < 4; i++) { printf("%d\n", pp[i](10, 2)); } system("pause"); }运行结果:主函数中的函数被替换为自己定义的函数。
2 函数指针和指针函数
以下内容引自<http://blog.csdn.net/htyurencaotang/article/details/11490081>辨别指针函数与函数指针最简单的方式就是看函数名前面的指针*号有没有被括号包含,如果被包含就是函数指针,反之则是指针函数。
2.1 指针函数
指针函数是指带指针的函数,即本质是一个函数。函数返回类型是某一类型的指针类型标识符 *函数名(参数表) int *f(x,y);首先它是一个函数,只不过这个函数的返回值是一个地址值。指针函数一定有函数返回值,而且在主调函数中,函数返回值必须赋给同类型的指针变量。例如
float *fun(); float *p; p = fun(a);
当一个函数声明其返回值为一个指针时,实际上就是返回一个地址给调用函数,以用于需要指针或地址的表达式中。
由于返回的是一个地址,所以类型说明符一般都是int。例如:
int *GetDate(); int * aaa(int,int);
2.2 函数指针
函数指针是指向函数的指针变量,即本质是一个指针变量。int (*f)(int x); /*声明一个函数指针 */ f=func; /*将func函数的首地址赋给指针f */指向函数的指针包含了函数的地址,可以通过它来调用函数。声明格式如下:
类型说明符 (*函数名)(参数)例如:
void (*fptr)();把函数的地址赋值给函数指针,可以采用下面两种形式:
(1)fptr = &Function; (2)fptr = Function;取地址运算符&不是必需的,因为一个函数标识符就表示了它的地址。
如果是函数调用,还必须包含一个圆括号括起来的参数表。
通过指针调用函数,可以采用如下两种方式:
(1)x=(*fptr)(); (2)x=fptr();
第二种格式看上去和函数调用无异,但是有些程序员倾向于使用第一种格式,因为它明确指出是通过指针而非函数名来调用函数的。下面举一个例子:
void (*funcp)(); void FileFunc(),EditFunc(); main() { funcp = FileFunc; (*funcp)(); funcp = EditFunc; (*funcp)(); } void FileFunc() { printf(FileFunc\n); } void EditFunc() { printf(EditFunc\n); }运行结果:
FileFunc EditFunc
3 劫持函数
#include<stdio.h> #include<stdlib.h> #include<Windows.h> void printf1() { printf("11111"); } void printf2() { printf("22222"); } void printf3() { printf("33333"); } void newprintf1() { MessageBoxA(0, "11111", "11111", 0); } void newprintf2() { MessageBoxA(0, "22222", "22222", 0); } void newprintf3() { MessageBoxA(0, "33333", "33333", 0); } void main() { void(*p[3])() = { printf1, printf2, printf3 };//函数指针数组 printf("%p", p);//数组的地址 void(*px[3])() = { newprintf1, newprintf2, newprintf3 }; for (int i = 0; i < 3; i++) { printf("\n%p", px[i]);//打印三个函数的地址 } while (1) { for (int i = 0; i < 3; i++) { printf("\n"); p[i]();//挨个调用函数 printf("\n"); } Sleep(3000); } } void main1() { void(*p)() = printf1; printf("\n%p", &p); printf("\n%p,%p", printf1, newprintf1);//打印地址 while (1) { printf("\n"); p(); Sleep(3000); } }
劫持模块
#include<stdlib.h> #include<stdio.h> //导出函数,可以加载的时候调用 _declspec(dllexport) void go() { //改变一个变量,需要变量的地址 //改变一个指针,需要指针的地址 void(**p)() = (void(**)())0x2af8ac; *p =(void(*)()) 0x2d1010; } _declspec(dllexport) void go1() { void(*p[3])(); //指针数组,批量管理函数地址 p[0] = 0x291030; p[1] = 0x291050; p[2] = 0x291070; void(**pp)() = 0x22fa54;// for (int i = 0; i < 3; i++) { *(pp+i) = p[i];//批量改变指针 } }
相关文章推荐
- C/C++常考面试题(1)
- HDU 5665 lucky
- 华为机试练习ex013_cpp之操作系统任务调度问题
- C++语法细节笔记
- c++ 实现atoi()函数
- C语言编辑器获取数组中元素个数
- 对称矩阵 压缩存储
- C语言中各种基本数据类型在内存中的存储方式
- 栈的链式实现(C语言)
- C++ String写时拷贝(Copy On Write)
- leetcode——链表快排
- 智能指针C++
- Cuda学习笔记(四)——在vs2010中配置.cpp和.cu文件
- 【C++】C++对象内存模型简介
- 串口通信 收发数据
- 使用c++中优先级队列
- OpenCV2.4.10之samples_cpp_tutorial-code_learn-----ImgProc(图像处理)
- Minimum Window Substring
- c++语言上机指导实用教程第三章3.1练习4
- c++之引用的本质