前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C 、汇编入门与逆向分析

C 、汇编入门与逆向分析

作者头像
小小咸鱼YwY
发布2022-05-09 15:23:23
5550
发布2022-05-09 15:23:23
举报
文章被收录于专栏:python-爬虫

c基础

C基本数据类型

代码语言:javascript
复制
char  short  int  float  long  double
所占字节 32和64位系统有所区别  sizeof()

数据结构

代码语言:javascript
复制
数组、链表、栈、队列、tree

++i

i++

--i

运算符与优先级

循环结构、选择结构

代码语言:javascript
复制
if(a<1){

   xxx

}else if(a==1){

   xxx

}else{

   xxx

}

switch(a){ //a整形数据

    case 1:

        xxx

    case 2:

        xxx

    case  3:

        xxx

    default:

        xxx

}

for(int i=0;i<100;i++){

    xxx

}

while(i<100){

    xxxx

}

do{

    xxx

}while(i<100)



int *p[]= {};

指针

内存的地址,C语言允许用一个变量来存放指针,这种变量称为指针变量。指针变量可以存放基本类型数据的地址,也可以存放数组、函数以及其他指针变量的地址。

结构体

代码语言:javascript
复制
struct Stu{
    char *name;  
    int num;  
    int age;  
    char group;  
    float score;  
};
或
typedef struct{
    char *name;  
    int num;  
    int age;  
    char group;  
    float score;  
}Stu;

结构体变量必须初始化,malloc、new
C
Stu *stu = malloc(sizeof(Stu))

C++
Stu *stu = new Stu()
stu->age
stu.age

C内存布局、分配方式

  • 内存布局
  • 分配方式

一个程序本质上都是由 Bss 段、Data段、Text段三个组成的

  • Text段

通常是指用来存放程序执行二进制代码

  • Bss段

一般是指用来存放程序中未初始化的全局变量

  • Data段

包括三部分 heap(堆)、stack(栈)和静态数据区。

  • 堆(heap):用于存放进程执行中被动态分配的内存段。它的大小并不固定,可动态扩张或缩减。malloc或new(C++)申请,需主动释放free、delete,否则会造成内存泄漏
  • 栈(stack):编译器自动分配释放,存放函数传参,局部变量,函数括弧“{}”中定义的变量(但不包含static声明的变量。static意味着在数据段中存放变量
  • 静态数据区: 已初始化的全局变量、静态变量和常量。
代码语言:javascript
复制
int a = 0; //全局初始化区,静态数据区
char *p1; //全局未初始化区 bss段
char* func(){//写法正确
  char *str = "hello,world";
  return str;
}
char* func1(){//写法错误,数组是不能作为函数返回值的,编译器把数组名认为是局部变量(数组)的地址,所以要用指针代替
  char str[20] = "hello,world";//如果非要返回,可以用static修饰
  return str;
}
char* func2(){
  char *str = (char*)malloc(20);
  str = "hello,world";
  return str;//返回堆内存的指针
}
int main(int argc, const char*argv[])
{
    static int a = 0; //全局(静态)初始化区,静态数据区
    int b; //栈
    char s[10] = "abc"; //字符串和s都是栈区,字符数组s在栈区分配内存
    char *p3 = "bilei"; //"bilei"在常量区,p3在栈区    
    p2 = (char *)malloc(20); //分配成功堆区
    //p2用完后必须主动释放
    free(p2);
    p2=NULL;//防止产生野指针。所谓野指针,即它指向的内存已被释放,单指针本身未释放,它指向的一块“垃圾”
}

汇编

常用指令

代码语言:javascript
复制
push、pop、add、sub、mov、lea、ldr、str、cmp、bl、blx、call(x86)

ret
代码语言:javascript
复制
push 压栈 pusb rbp
pop 出站. pop rbp
add :add eax,2 //eax = eax+2
sub :sub eax,2 //eax = eax-2
mov :赋值指令
ldr :读取
str :存储

mov R0, 1 //将0赋值给寄存器r0
LDR  R0,[R1]           // 将存储器地址为R1的字数据读入寄存器R0
LDR  R0,[R1,R2]        // 将存储器地址为R1+R2的字数据读入寄存器R0
LDR  R0,[R1,#8]        // 将存储器地址为R1+8的字数据读入寄存器R0
LDR  R0,[R1,R2]!       // 将存储器地址为R1+R2的字数据读入寄存器R0,并将新地址R1+R2写入R1
LDR  R0,[R1,#8]!       // 将存储器地址为R1+8的字数据读入寄存器R0,并将新地址R1+8写入R1
LDR  R0,[R1],R2        // 将存储器地址为R1的字数据读入寄存器R0,并将新地址R1+R2写入R1
LDR  R0,[R1,R2,LSL#2]! // 将存储器地址为R1+R2×4的字数据读入寄存器R0,并将新地址R1+R2×4写入R1
LDR  R0,[R1],R2,LSL#2  // 将存储器地址为R1的字数据读入寄存器R0,并将新地址R1+R2×4写入R1
STR R0,[R1],#8  // 将R0中的字数据写入以R1为地址的存储器中,并将新地址R1+8写入R1
STR R0,[R1,#8]  // 将R0中的字数据写入以R1+8为地址的存储器中
堆栈平衡

函数执行前后,函数里面的堆栈要保持不变,如果变了,也就是用了push、sub sp ,0x10,那么一定要在函数ret之前,恢复对栈原来的样子 (pop, add sp, 0x10). 如果堆栈不平衡,程序就会崩溃

arm64
代码语言:javascript
复制
rax,rbx,rcx,rdx,esi,edi,rbp,rsp,r8,r9,r10,r11,r12,r13,r14,r15。其中:

rax 作为函数返回值使用。
rsp 栈指针寄存器,指向栈顶
rdi,rsi,rdx,rcx,r8,r9 用作函数参数,依次对应第1参数,第2参数。。。
rbx,rbp,r12,r13,14,15 用作数据存储,调用子函数之前要备份它,以防他被修改
r10,r11 用作数据存储,使用之前要先保存原值
代码语言:javascript
复制
main:                                   # @main
        push    rbp //压栈
        mov     rbp, rsp 
        sub     rsp, 48 //分配栈空间 rsp栈顶指针 
        mov     dword ptr [rbp - 4], edi
        mov     qword ptr [rbp - 16], rsi
        mov     eax, dword ptr [.L__const.main.s]
        mov     dword ptr [rbp - 24], eax
        movabs  rax, offset .L.str
        mov     qword ptr [rbp - 40], rax
        mov     edi, 20
        call    malloc
        mov     qword ptr [rbp - 32], rax
        mov     rdi, qword ptr [rbp - 32]
        call    free
        mov     qword ptr [rbp - 32], 0
        xor     eax, eax
        add     rsp, 48  //堆栈平衡
        pop     rbp //出站
        ret
a:
        .long   0                               # 0x0

p1:
        .quad   0

.L__const.main.s:
        .asciz  "abc"

.L.str:
        .asciz  "bilei"
armv7
代码语言:javascript
复制
main:
        push    {r11, lr}
        mov     r11, sp
        sub     sp, sp, #24
        str     r0, [r11, #-4]
        str     r1, [r11, #-8]
        ldr     r0, .LCPI0_0
        str     r0, [sp, #8]
        ldr     r0, .LCPI0_1
        str     r0, [sp]
        mov     r0, #20
        bl      malloc
        str     r0, [sp, #4]
        ldr     r0, [sp, #4]
        bl      free
        mov     r0, #0
        str     r0, [sp, #4]
        mov     sp, r11
        pop     {r11, lr}
        bx      lr
.LCPI0_0:
        .long   6513249                         @ 0x636261
.LCPI0_1:
        .long   .L.str
a:
        .long   0                               @ 0x0

p1:
        .long   0

.L.str:
        .asciz  "bilei"
armv8
代码语言:javascript
复制
main:                                   // @main
        sub     sp, sp, #64                     // =64
        stp     x29, x30, [sp, #48]             // 16-byte Folded Spill
        add     x29, sp, #48                    // =48
        stur    w0, [x29, #-4]
        stur    x1, [x29, #-16]
        adrp    x8, .L__const.main.s
        add     x8, x8, :lo12:.L__const.main.s
        ldr     w9, [x8]
        str     w9, [sp, #24]
        adrp    x8, .L.str
        add     x8, x8, :lo12:.L.str
        str     x8, [sp, #8]
        mov     x0, #20
        bl      malloc
        str     x0, [sp, #16]
        ldr     x0, [sp, #16]
        bl      free
        str     xzr, [sp, #16]
        mov     w9, wzr
        mov     w0, w9
        ldp     x29, x30, [sp, #48]             // 16-byte Folded Reload
        add     sp, sp, #64                     // =64
        ret
a:
        .word   0                               // 0x0

p1:
        .xword  0

.L__const.main.s:
        .asciz  "abc"

.L.str:
        .asciz  "bilei"

实战

学习网站:https://godbolt.org/ https://files.cnblogs.com/files/pythonywy/测试so.zip

代码语言:javascript
复制
#include <stdlib.h>
#include <stdio.h>
typedef struct{
  int age;
  char *name;
  int grade;
  short fenshu;
   
}Student;

struct Test{
  int num;
  char c;
  short data;
   
};

int sum(int a, int b){
  return a+b;
}
void sum1(int *a){
  a[1] = 2;
}
int main(int argc, const char * argv[]) {
   
//  char *result_func = func();
  for(int i=0;i<100;i++){
    printf("%s\n",func3());
  }
  for(int i=0;i<100;i++){
    printf("%s\n",func1());
  }
  for(int i=0;i<100;i++){
    printf("%d\n",func2());
  }
   int a=2;
  int array[8] = {1,2,3,4,5,6,7,8};
  int array1[8] = {1,2,3,4,5,6,7,8};
  int array2[8] = {1,2,3,4,5,6,7,8};
  int array3[][3] = {{1,2,3},{4,5,6},{7,8,9}};
  int *p_array[8] = {array,array1,array2};
  int (*q_array)[3] = &array3[0];
  int (*fun_p)(int a, int b);//函数指针
  fun_p = sum;//将函数的首地址赋值给fun_p
  int size1 =(int) sizeof(Test);
  Student *stu = new Student();//申请内存空间,也可以mac
  int size =(int) sizeof(Student);
  stu->name = "bilei";
  stu->age = 8;
  stu->grade = 2;
  int a = (*fun_p)(1,2);
  char *q = (char*)malloc(8);
  q = (stu->name);
  int aa = *(q +1);
  a = stu->name[1];
  if(a>0){
    a = sum(a, stu->age);
  }
  switch (a){
    case 1:
      a = a<<1;
    case 2:
      a = a<<2;
    case 3:
      a = a<<3;
    case 4:
      a = a<<4;
    default:
      a = a;
  }
  stu->grade = a;
  short b = 2;
  long l = 3;
  char c = 'v';
  char *p = "hello,world";
  char q1 = *(p+1);
  char s = *p+1;
  sum1(array);
   
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-03-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • c基础
    • C基本数据类型
      • 数据结构
        • 运算符与优先级
          • 循环结构、选择结构
            • 指针
              • 结构体
                • C内存布局、分配方式
                • 汇编
                  • 常用指令
                    • 堆栈平衡
                    • arm64
                    • armv7
                    • armv8
                • 实战
                相关产品与服务
                数据保险箱
                数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档