C语言
编译器 VS MSVC 4/72
gcc 2/72
linux mingw gcc 14/72
不同编译器对免杀效果不一样,参数不同效果也不一样
进程链
powershell 运行没杀
双击运行干掉了
原因是进程链
powershell——》helloworld.exe——》 微软信任powershell
双击——》独立出来的程序——》explorer——》
C语言
变量
全局变量:存放再rdata和data
局部变量:不存在文件中,用到时才申请一块内存空间,只有解析代码才能独出来,所以可以过静态免杀。只有动态杀毒才能检测出来.
char h1[] = "abcdfj";
这串代码实际上是下面这样
char h1[6] = {0};
memcpy(h1,abcdfj,sizeof(h1));
保存在了程序中。
char h1[] = { 'a','b','c','d','e','f' ,0};
在程序中就没加载了
数组
数组的本质: 就是存放同一数据的变量.
数组名: 指向这一组数据的地址常量.
int ary[256]; //int代表数组类型,ary代表数组名,256代表数组的大小,256*4(int是四字节)
函数
函数的本质: text节的一部分内存的符号化
函数种类: 分为导出函数和内部函数,dll
导出函数会在解析pe结构中看到
内部函数只有在编译前能看到,或者配合符号文件(pdb)才能看到(静态免杀 )
命令行传参
int main(int argc,char* argv[])
argc: 命令行参数的个数,也就是argv的个数,默认为1(算上程序本身了)
argv: 命令行参数的数组,argv[0],代表第一个字符串参数的地址.程序本身
int main(int argc,char* argv[])
{
printf("argc = %d\n",argc);
printf("argv = %s\n", argv[0]);
printf("argv = %s\n", argv[1]);
}
结构体
结构体本质: 不同类型的数据的整合符号化
关键字struct
指针
指针的本质:一块内存的符号化,只不过这个内存保留的的是一个地址
指针的大小:永远是四个字节,不管是int类型、char、还是函数指针、数组指针。为什么是四字节,因为它是指向一个32位的地址。
指针的加减法:看类型来,如果是int就是四字节、char就是1字节。
指针的本质:
char* p = NULL;
printf("%x\n", &((char*)p)[1]); //如果直接访问p会报错,因为地址为空,但是取地址位置+1是可以的
函数指针:如何定义函数指针int(*pFUN)(void)
int (*pFUN)(void);
char shellcode[] = { 0xcc,0xdd };
int main()
{
//把shellcode当成函数来执行
pFUN = (int(*) (void)) & shellcode;
printf("%x\n", pFUN);
}
数组指针:
char ddd[5];
# 存放的是地址
char(*arg1)[5] = &ddd;
char ddd[5] = { 1,2,3,4,5 };
char(*arg1)[5] = &ddd;
printf("%d\n", *arg1[0]);// 1
printf("%d\n", (*arg1)[1]); // 2 这里不能不要()。优先级的问题
printf("%d\n", arg1[0][1]); // 2
printf("%d\n", (**arg1)+1); // 2
int ary[2][4] = { 1,2,3,4,1,2,3,4 };
int(*pary)[4] = ary;
printf("%d\n", pary[0][0]); //1
printf("%x\n", pary); //a84ffb78
printf("%x\n", pary[0]+1); //a84ffb7c 加了4,本质上就是加了个int
printf("%x\n", pary+1); //a84ffb88 加了十六,本质上就是加了个int*4
指针数组:存放地址的数组
char* dd = (char*)"hello";
char* ary[5] = { (char*)"hello1",(char*)"hello2",(char*)"hello3",(char*)"hello4",(char*)"hello5" };
printf("%s\n", ary[2]); //hello3
共用体
多个变量公用同一个内存,结构体的大小是根据最大的数据类型来算的,比如在下面的程序中int就是最大的,所以是四个字节。
效果一,int覆盖char:
效果二,char覆盖int:
枚举类型
enum dd
{
d1, d2, d3, d4
};
int main()
{
dd d;c
d = d1;
printf("%d %d %d %d", d,d2,d3,d4);
}
0 1 2 3
设置初始值
enum dd
{
d1 = 7, d2, d3, d4
};
int main()
{
dd d;
d = d1;
printf("%d %d %d %d", d,d2,d3,d4);
}
7 8 9 10