3 安卓逆向c语言基础

104 阅读3分钟

1 安装一个mingw64,配置好环境变量之后保证能在命令行中执行gcc

2 下载clion

3 C语言的字符串操作

char v1 = 'o';
char v2[] = {'o','u','y','g','y','\0'};
char v3[] = "oygy";
char v4[] = "张三他爸";
printf("v1的值%c\n",v1);
printf("v2的值%s\n",v2);
printf("v3的值%s\n",v3);
printf("v4的值%s\n",v4);
printf("Hello, World!\n");


printf("%s的长度为:%llu\n",v2,sizeof(v2)/sizeof(char));
printf("%s的长度为:%llu\n",v4,sizeof(v4)/sizeof(char));  // 字节长度
printf("%s的长度为:%llu\n",v4,strlen(v4));  // 真实长度,配合#include <string.h>

整型

// 在c语言中每个数字(整型)是占用4个字节
int i1 = 123;
printf("%d的长度%llu\n",i1,sizeof i1);

C语言的指针


// 在c语言中每个数字(整型)是占用4个字节
int i1 = 123;
printf("%d的长度%llu\n",i1,sizeof i1);

// 指针
printf("%d 的指针是 %p\n",i1,&i1);

// 指针的指针
int* i2 = &i1;
printf("%p 的指针是 %p\n",i2,&i2);

// 通过指针找值
int i3 = *i2;
printf("%p锁指向的值 %d\n",i2,i3);


// 指针的存在是为了共享内存空间(数据共享)
// & 表示取某个变量的地址
// * 表示取某个内存地址的值
// 一个指针占用8个字节

char v34[80]; //[6,1,,,,,]
char *v28;
v28 = (char *) &v34;  // v28 = v34;
// char *v28 = &v34;

char v36[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g'};

int v29 = 0;
do {
    sprintf(v28, "%02x", v36[v29++]); //  'a'
    v28 += 2;
} while (v29 != 7);

printf(v34);

C语言的构造方法

struct Person{
    char name[30];
    int age;
};


struct node{
    int data;
    struct node *next;
};

struct Serson
{
    int data;
    struct Serson *next;
    struct Serson *prev;
};

C语言的结构体

// 结构体
struct Person s1 = {"andy",10};
struct Person s2 = {"kate",19};
printf("s1的名字%s,s1的age是%d\n",s1.name,s1.age);
printf("s2的名字%s,s2的age是%d\n",s2.name,s2.age);

// 结构体的指针
struct Person * pp = &s1;

// 结构体指针取值(两种取值方式)
printf("结构体指针取值%s\n",(*pp).name);
printf("结构体指针取值%d\n",pp->age);

单向链表

 struct node n3 = {30};
    struct node n2 = {20,&n3};
    struct node n1 = {10,&n2};
    printf("%d\n",n1.data);  // 10
    printf("%d\n",n1.next->data); // 20
    printf("%d\n",n1.next->next->data); // 30

双向链表

struct Serson p3 = { 33 };
    struct Serson p2 = { 22 };
    struct Serson p1 = { 11 };

    p1.next = &p2;

    p2.next = &p3;
    p2.prev = &p1;

    p3.prev = &p2;

    printf("p1的值: %d\n", p1.data);
    printf("p2的值: %d\n", p1.next->data);
    printf("p3的值: %d\n", p1.next->next->data);

    printf("p3的值: %d\n", p3.data);
    printf("p2的值: %d\n", p3.prev->data);
    printf("p1的值: %d\n", p3.prev->prev->data);

双向环状链表

struct Serson p6 = { 66 };
struct Serson p5 = { 22 };
struct Serson p4 = { 11 };
p4.next = &p5;
p4.prev = &p6;

p5.next = &p6;
p5.prev = &p4;

p6.prev = &p5;
p6.next = &p4;

printf("p4的值: %d\n", p4.data);
printf("p5的值: %d\n", p4.next->data);
printf("p6的值: %d\n", p4.next->next->data);

printf("p4的值: %d\n", p4.next->next->next->data);
printf("p5的值: %d\n", p4.next->next->next->next->data);
printf("p6的值: %d\n", p4.next->next->next->next->next->data);

预处理和头文件

现在文件上部分定义

等同于定义了一个函数,然后main函数内部调用该函数

#define ADD(x1,x2)(x1*x2)
int dd = ADD(2+1,3);  // 6
printf("%d\n",dd);

预处理,在程序编译之前会先运行的。

# include <stdio.h>

# define ME  200
# define SIZE  18

int main() {
    int data = 19;

    printf("%d-%d-%d \n", ME, SIZE, data);
    return 0;
}
# include <stdio.h>

# define ADD(x1, x2)(x1+x2+100)

int main() {
    int data = ADD(11, 22); // 11+22+100
    printf("结果:%d \n", data);
    return 0;
}
# include <stdio.h>

# define DB(x1, x2)(x1*x2)

int main() {
    int data = DB(2 + 1, 4);  // 2+1*4 = 6
    printf("结果:%d \n", data);
    return 0;
}
项目目录
├── main.c
├── utils.c
└── utils.h
// utils.h

int plus(int v1);
// utils.c

int plus(int v1){
    return v1 + 100;
}
# include <stdio.h>
# include "utils.h"

int main() {
    int data = plus(100);
    printf("结果:%d \n", data);
    return 0;
}

比如后期,我们要进行JNI开发时,我们会在自己的c文件用去引入C语言中提供、JNI中提供一些头文件,才能使用头文件中的功能。