逆向_07数据类型(C语言)及调用约定

  1. 裸函数
  2. 有参返回结果的裸函数
  3. 函数调用约定
  4. 寻找程序的入口
  5. 数据类型/数据存储
  6. ascii码表
  7. 内存图

裸函数

void __declspec(naked) function(){
    __asm{
        ret
    }
}
  • 编译器不会帮我们填充代码,需要手动去写代码

有参返回结果的裸函数

void __declspec(naked) function(int x,int y){
    __asm{
        //保留调用前的堆栈
        push ebp
        //提升堆栈
        mov ebp,esp
        sub esp,0x40
        //保留上下文
        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
    }
}

函数调用约定

调用约定 参数压栈顺序 平衡堆栈
__cdecl 从右向左入栈 调用者清理堆栈
__stdcall 从右向左入栈 自身清理堆栈
__fastcall ECX/EDX传送前两个,剩下的从右至左入栈 自身清理堆栈

寻找程序的入口

  1. kernel32.mainCRTStartup()

    • 所做的操作
      • GetVersion()
      • _heap_init()
      • GetCommandLineA()
      • _crtGetEnvironmentStringsA()
      • _setargv()
      • _setenvp()
      • _cinit()
  2. 再由上边的函数调用main函数

  3. main函数在mainCRTStartup()中的定义

    mark

  • 寻找方法
    • 最简单的
      • 查找传递了三个参数的函数即为主函数

数据类型/数据存储

  • C语言数据类型

    • 基本类型
      • 整数类型:char/byte(1)、short(2)、int(4)、long(4)
      • 浮点类型:float、double
    • 构造类型
      • 数组类型:
      • 结构体类型
      • 共用体(联合)类型
    • 指针类型
    • 空类型(void)
  • 学习数据类型的三要素

    1. 存储数据的宽度
    2. 存储数据的格式
    3. 作用范围(作用域)
  • 有无符号的区别

    • 默认是有符号的
    • 需要注意的地方
      • 类型转换
      • 数学运算
  • 浮点数类型

    • float和double在存储方式上都遵从IEEE的规范

    • float的存储方式

      • mark
    • double的存储方式

      mark

    • 将一个float型转化为内存存储格式的步骤为:

      1. 先将这个实数的绝对值转化为二进制
      2. 将这个二进制格式实数的小数点左移或者右移n位,直到小数点移动到第一个有效数字的右边
      3. 从小数点右边第一位开始数出二十三位数字放入第22位到第0位
      4. 如果实数为正,则在第31位放入“0”,否则放入“1”
      5. 如果n是左移得到的,说明指数是正数,第30位放入“1”,如果n是右移得到的或者n=0,则在第30位放入“0”
      6. 如果n是左移得到的,则将n减去1后化为二进制,并在左边加“0”补足7位,放入第29到第23位,如果n是右移得到的或者n=0,则将n化为二进制,并在左边加“0”补足7位,再各位求反,放入第29到第23位

ascii码表

二进制 十进制 十六进制 字符/缩写 解释
00000000 0 00 NUL (NULL) 空字符
00000001 1 01 SOH (Start Of Headling) 标题开始
00000010 2 02 STX (Start Of Text) 正文开始
00000011 3 03 ETX (End Of Text) 正文结束
00000100 4 04 EOT (End Of Transmission) 传输结束
00000101 5 05 ENQ (Enquiry) 请求
00000110 6 06 ACK (Acknowledge) 回应/响应/收到通知
00000111 7 07 BEL (Bell) 响铃
00001000 8 08 BS (Backspace) 退格
00001001 9 09 HT (Horizontal Tab) 水平制表符
00001010 10 0A LF/NL(Line Feed/New Line) 换行键
00001011 11 0B VT (Vertical Tab) 垂直制表符
00001100 12 0C FF/NP (Form Feed/New Page) 换页键
00001101 13 0D CR (Carriage Return) 回车键
00001110 14 0E SO (Shift Out) 不用切换
00001111 15 0F SI (Shift In) 启用切换
00010000 16 10 DLE (Data Link Escape) 数据链路转义
00010001 17 11 DC1/XON (Device Control 1/Transmission On) 设备控制1/传输开始
00010010 18 12 DC2 (Device Control 2) 设备控制2
00010011 19 13 DC3/XOFF (Device Control 3/Transmission Off) 设备控制3/传输中断
00010100 20 14 DC4 (Device Control 4) 设备控制4
00010101 21 15 NAK (Negative Acknowledge) 无响应/非正常响应/拒绝接收
00010110 22 16 SYN (Synchronous Idle) 同步空闲
00010111 23 17 ETB (End of Transmission Block) 传输块结束/块传输终止
00011000 24 18 CAN (Cancel) 取消
00011001 25 19 EM (End of Medium) 已到介质末端/介质存储已满/介质中断
00011010 26 1A SUB (Substitute) 替补/替换
00011011 27 1B ESC (Escape) 逃离/取消
00011100 28 1C FS (File Separator) 文件分割符
00011101 29 1D GS (Group Separator) 组分隔符/分组符
00011110 30 1E RS (Record Separator) 记录分离符
00011111 31 1F US (Unit Separator) 单元分隔符
00100000 32 20 (Space) 空格
00100001 33 21 !
00100010 34 22
00100011 35 23 #
00100100 36 24 $
00100101 37 25 %
00100110 38 26 &
00100111 39 27
00101000 40 28 (
00101001 41 29 )
00101010 42 2A *
00101011 43 2B +
00101100 44 2C ,
00101101 45 2D -
00101110 46 2E .
00101111 47 2F /
00110000 48 30 0
00110001 49 31 1
00110010 50 32 2
00110011 51 33 3
00110100 52 34 4
00110101 53 35 5
00110110 54 36 6
00110111 55 37 7
00111000 56 38 8
00111001 57 39 9
00111010 58 3A :
00111011 59 3B ;
00111100 60 3C <
00111101 61 3D =
00111110 62 3E >
00111111 63 3F ?
01000000 64 40 @
01000001 65 41 A
01000010 66 42 B
01000011 67 43 C
01000100 68 44 D
01000101 69 45 E
01000110 70 46 F
01000111 71 47 G
01001000 72 48 H
01001001 73 49 I
01001010 74 4A J
01001011 75 4B K
01001100 76 4C L
01001101 77 4D M
01001110 78 4E N
01001111 79 4F O
01010000 80 50 P
01010001 81 51 Q
01010010 82 52 R
01010011 83 53 S
01010100 84 54 T
01010101 85 55 U
01010110 86 56 V
01010111 87 57 W
01011000 88 58 X
01011001 89 59 Y
01011010 90 5A Z
01011011 91 5B [
01011100 92 5C \
01011101 93 5D ]
01011110 94 5E ^
01011111 95 5F _
01100000 96 60 `
01100001 97 61 a
01100010 98 62 b
01100011 99 63 c
01100100 100 64 d
01100101 101 65 e
01100110 102 66 f
01100111 103 67 g
01101000 104 68 h
01101001 105 69 i
01101010 106 6A j
01101011 107 6B k
01101100 108 6C l
01101101 109 6D m
01101110 110 6E n
01101111 111 6F o
01110000 112 70 p
01110001 113 71 q
01110010 114 72 r
01110011 115 73 s
01110100 116 74 t
01110101 117 75 u
01110110 118 76 v
01110111 119 77 w
01111000 120 78 x
01111001 121 79 y
01111010 122 7A z
01111011 123 7B {
01111100 124 7C |
01111101 125 7D }
01111110 126 7E ~
01111111 127 7F DEL (Delete) 删除

内存图

代码区(if/else/while等)
堆栈(参数、局部变量、堆、全局变量区、常量区)
堆(动态申请的、大小是可变的、可读可写)
全局变量区(可读可写)
常量区(只读)
  • 全局变量的特点

    1. 全局变量在程序编译完成后地址就已经确定下来了,只要程序启动,全局变量就已经存在了,启动后里面,是否有值取决于声明时是否给定了初始值,如果没有,默认为0

    2. 全局变量的值可以被所有函数所修改,里面存储的是最后一次修改的值.

    3. 全局变量所占内存会一直存在,知道整个进程结束.

    4. 全局变量的反汇编识别:

      MOV 寄存器,byte/word/dword ptr ds:[0x12345678]
      通过寄存器的宽度,或者byte/word/dword 来判断全局变量的宽度
    5. 全局变量就是所谓的基址

  • 局部变量的特点:

    1. 局部变量在程序编译完成后并没有分配固定的地址

    2. 在所属的方法没有被调用时,局部变量并不会分配内存地址,只有当所属的程序被调用了,才会在堆栈中分配内存.

    3. 当局部变量所属的方法执行完毕后,局部变量所占用的内存将变成垃圾数据.局部变量消失.

    4. 局部变量只能在方法内部使用,函数A无法使用函数B的局部变量.

    5. 局部变量的反汇编识别:

      [ebp-4]
      [ebp-8]
      [ebp-0XC]

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 787772394@qq.com

文章标题:逆向_07数据类型(C语言)及调用约定

本文作者:二豆子·pwnd0u

发布时间:2020-09-24, 17:41:37

最后更新:2023-05-18, 09:49:41

原始链接:http://blog.codefat.cn/2020/09/24/%E9%80%86%E5%90%91-07%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B-C%E8%AF%AD%E8%A8%80/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏

/*爱心代码*/ /*雪花效果*/ /*百度代码自动提交*/