不正经学 C & PE 历程实录
本帖最后由 HackYike 于 2024-4-13 19:47 编辑花了好长时间,终于勉强能解释发生了什么,记录一下。
ebp+4与函数内数组的存储
第一份:
#include "stdafx.h"
void Attack()
{
while(1)
{
printf("Attack!\r\n");
}
getchar(); // 暂停执行,等待输入的功能
}
int main(int argc, char* argu[])
{
int arr = {0};
/*
arr数组,所以最大索引值为4,arr的地址为ebp-4,arr的地址为ebp-8,以此类推。
地址为ebp的是上级函数的ebp值,ebp+4是上级函数call下一条指令的eip,即main函数执行完毕后返回的地址,
当把ebp+4的值赋为Attack函数的指针时,程序将执行Attack函数
arr为ebp,arr恰好是ebp+4
*/
arr =(int)Attack; //取Attack函数指针强行转换为int,赋值给arr
return 0;
}
第二份:
#include "stdafx.h"
#include <stdio.h>
void HelloWorld()
{
int i = 0;
/*这里的i压入堆栈,地址为ebp-4*/
int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
/*
注意这里的数组在堆栈中的保存方式,a==10,地址为ebp-8;a==9,地址为ebp-0xC
所以ebp-4(即i)为a,当i==10时,a=0的赋值语句恰好把i改成0
*/
for(i=0; i<=10; i++)
{
a = 0;
printf("Hello World\n");
}
}
int main(int argc, char* argv[])
{
HelloWorld();
getchar(); //暂停执行,等待输入的功能
return 0;
}
本帖最后由 HackYike 于 2024-3-26 00:39 编辑
int main()
{
char arr = {2, 3, 4, 5, 6};
char* pa = arr;
__asm
{
mov al,
mov ,al
}
printf("%d\n", *(pa-5));
return 0;
}
这完全是学python时想不到的做法!为了输出6,试了好久…… 这些代码在调试模式下可以辅助理解栈,是个不错的方式。
不过生产环境不建议这么玩,因为编译优化可能导致未知的结果。这些东西属于黑箱,不同编译器不同优化开关有可能导致不同的现象 yes2 发表于 2024-3-26 08:55
这些代码在调试模式下可以辅助理解栈,是个不错的方式。
不过生产环境不建议这么玩,因为编译优化可能导致 ...
是的,所以之前学c时老师几乎不会涉及到栈区的细节。这让我大开眼界! // int 型,值为100(十进制),定位
char arr = {
0x00,0x64,0x00,0x00,0x00,0x05,0x06,0x07,0x07,0x09,
0x00,0x20,0x10,0x03,0x03,0x0C,0x00,0x00,0x44,0x00,
0x00,0x33,0x00,0x47,0x0C,0x0E,0x00,0x0D,0x00,0x11,
0x00,0x00,0x00,0x02,0x64,0x00,0x00,0x00,0xAA,0x00,
0x00,0x00,0x64,0x10,0x64,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x02,0x00,0x74,0x0F,0x41,0x64,0x00,0x00,
0x00,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,
0x00,0x02,0x74,0x0F,0x41,0x00,0x06,0x08,0x00,0x00,
0x00,0x00,0x00,0x64,0x00,0x0F,0x00,0x00,0x0D,0x00,
0x00,0x00,0x23,0x00,0x00,0x64,0x00,0x00,0x00,0x00
};
int main()
{
int* p_i = (int*) arr;
int k = 0;
while (k<97)
{
char* p_in = (char*) p_i;
int* t = (int*) (p_in + k);
if (*t==100)
{
printf("%d:%d\n", k, t);
}
k++;
}
return 0;
} for(int k=0; k<97; k++)
{
if (*(int*)&arr == 100)
{
printf("%d:%d\n", k, t);
}
} yes2 发表于 2024-3-27 08:51
for(int k=0; k
我发出来是因为指针类型转换和解引用搅和在一起还不熟练。你这个编译不了,但我猜测似乎直接把 char 当 int 用了,这不符合题目要求。 福至心灵,似乎睡了一觉有了点茅塞顿开的感觉,好像昨天困扰我好久的东西今天突然一下子就明白到底发生了什么了!!!
#include "stdafx.h"
// 查找有几个id=1 level=8的结构体信息。
char arr[] =
{
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x07,0x09,
0x00,0x20,0x10,0x03,0x03,0x0C,0x00,0x00,0x44,0x00,
0x00,0x33,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,
0x00,0x00,0x00,0x02,0x64,0x00,0x00,0x00,0xAA,0x00,
0x00,0x00,0x64,0x01,0x00,0x00,0x00,0x08,0x00,0x00,
0x00,0x00,0x02,0x00,0x74,0x0F,0x41,0x00,0x00,0x00,
0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x0A,0x00,
0x00,0x02,0x57,0x4F,0x57,0x00,0x06,0x08,0x00,0x00,
0x00,0x00,0x00,0x64,0x00,0x0F,0x00,0x00,0x0D,0x00,
0x00,0x00,0x23,0x00,0x00,0x64,0x00,0x00,0x64,0x00
};
typedef struct TagPlayer
{
int id;
int level;
}Player;
int num(char* arr)
{
char* pc = arr;
int k = 0;
int res = 0;
while (k<93)
{
if ((*(int*)(pc+k))==1 && (*((int*)(pc+k)+1))==8)
{
res++;
}
k++;
}
return res;
}
int main()
{
int result = num(arr);
printf("%d\n", result);
return 0;
} int main()
{
for(int k=0; k<97; k++)
{
if (*(int*)&arr == 100)
{
printf("%d:%d\n", k, *(int*)&arr );
}
}
return 0;
}
--------------
输出:
1:100
34:100
44:100
57:100
61:100
95:100
页:
[1]
2