二进制C语言-数据类型
xiu裸函数
编译器不做任何分配,配合钩子执行自己想要的效果
普通的C程序可以正常执行,但是如下裸函数不允许直接调用
1 2 3 4
| void __declspec(naked) Add() { }
|

修改裸函数为普通C程序的运行模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
|
#include "stdafx.h"
int __declspec(naked) Add(int x,int y) { __asm { push ebp
mov ebp,esp sub esp,40
push ebx push esi push edi
mov eax,0xcccccccc mov ecx,0x10 lea edi,dword ptr ds:[ebp-0x40] rep stosd
mov eax,dword ptr ds:[ebp+0x8] add eax,dword ptr ds:[ebp+0xc]
pop edi pop esi pop ebx
mov esp,ebp pop ebp
ret } }
int main(int argc, char* argv[]) { Add(1,2); return 0;
}
|

调用约定

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
#include "stdafx.h"
int __cdecl ADD1(int x,int y) { return x + y; }
int __stdcall ADD2(int x,int y) { return x + y; }
int __fastcall ADD3(int x,int y) { return x + y; }
int main(int argc, char* argv[]) { ADD1(1,2); return 0;
}
|
__cdecl C语言默认的约定

__stdcall windowsapi用的约定


__fastcall 快速处理参数入栈(注意参数不能超过两个,不然没有足够的寄存器传参还是要用内存)

数据类型与数据存储
三要素
宽度
格式
作用域
数据类型
基本类型
整数类型
浮点类型
构造类型
数组类型
结构体类型
共用体类型
空类型
void
指针类型
数据存储形式
整数
char=byte
short=word
int=long=dword
有符号数与无符号数在比较大小,数学运算和类型转换的时候需要注意
有符号数
char i = 0xff; 默认就是有符号数
无符号数
unsigned char i = 0xff

运算的时候编译器会根据程序员确定的是有符号数还是无符号数来调用不同的JCC指令运算,但是不管有符号数还是无符号数,数据在内存里存储的值是一致的
浮点数
float(四字节)
1 2 3 4 5 6 7 8 9 10 11 12 13
|
#include "stdafx.h"
int main(int argc, char* argv[]) { float a = 8.25f; return 0;
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| 8.25--十进制
浮点数存储在内存中由三部分组成
1、先将这个数的绝对值转化为二进制 从下向上计位 8/2 0 | 4/2 0 | 2/2 0 | 1/2 1 | 从上向下计位(遇到0.4这种无限循环的小数部分根据精度有最大存储精度) 0.25*2=0.5 0 0.5*2=1.0 1
8.24----->1000.01
2、1000.01左移三位,相当于1.00001乘以2的三次方,指数为3,左移还是右移需要判断有效位,要把小数点移动到第一个有效位的右侧,比如整数部分为0,那么我们需要有效位为1的地方就需要右移,左移是正数,右移是负数
3、 小数点右侧第一个数开始数23个数放入尾数部分。 指数部分,左移第一位填1,右移就是0,剩余的七位用移动了几位减1 符号位:区分正数与负数,正数存0,负数存1
4、根据 符号位 指数部分 尾数部分的格式转换二进制为十六进制
|


-8.25只需要把符号位变为1即可,


0.25


double