吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 550|回复: 17
收起左侧

[学习记录] 不正经学 C & PE 历程实录

[复制链接]
HackYike 发表于 2024-3-24 17:46
本帖最后由 HackYike 于 2024-4-13 19:47 编辑

花了好长时间,终于勉强能解释发生了什么,记录一下。

ebp+4与函数内数组的存储
第一份:
[C++] 纯文本查看 复制代码
#include "stdafx.h"

void Attack()
{
        while(1)
        {
                printf("Attack!\r\n");
        }
        getchar(); // 暂停执行,等待输入的功能
}

int main(int argc, char* argu[])
{
        int arr[5] = {0};
        /*
        arr[5]数组,所以最大索引值为4,arr[4]的地址为ebp-4,arr[3]的地址为ebp-8,以此类推。
        地址为ebp的是上级函数的ebp值,ebp+4是上级函数call下一条指令的eip,即main函数执行完毕后返回的地址,
        当把ebp+4的值赋为Attack函数的指针时,程序将执行Attack函数

    arr[5]为ebp,arr[6]恰好是ebp+4
        */
        arr[6] =  (int)Attack; //取Attack函数指针强行转换为int,赋值给arr[6]

        return 0;
}



第二份:
[C++] 纯文本查看 复制代码
#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[9]==10,地址为ebp-8;a[8]==9,地址为ebp-0xC
        所以ebp-4(即i)为a[10],当i==10时,a[10]=0的赋值语句恰好把i改成0
        */
        for(i=0; i<=10; i++)
        {
                a[i] = 0;
                printf("Hello World\n");
        }
        
}


int main(int argc, char* argv[])
{
        HelloWorld();
        getchar(); //暂停执行,等待输入的功能
        return 0;
}

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

头像被屏蔽
sai609 发表于 2024-3-24 17:55
提示: 该帖被管理员或版主屏蔽
 楼主| HackYike 发表于 2024-3-26 00:23
本帖最后由 HackYike 于 2024-3-26 00:39 编辑

[C++] 纯文本查看 复制代码
int main()
{
    char arr[5] = {2, 3, 4, 5, 6};

    char* pa = arr;

    __asm
    {
        mov al,[ebp-4]
        mov [ebp-13],al
    }
    
    printf("%d\n", *(pa-5));

    return 0;
}


这完全是学python时想不到的做法!为了输出6,试了好久……
yes2 发表于 2024-3-26 08:55
这些代码在调试模式下可以辅助理解栈,是个不错的方式。
不过生产环境不建议这么玩,因为编译优化可能导致未知的结果。这些东西属于黑箱,不同编译器不同优化开关有可能导致不同的现象

免费评分

参与人数 1吾爱币 +1 收起 理由
HackYike + 1 热心回复!

查看全部评分

 楼主| HackYike 发表于 2024-3-26 12:22
yes2 发表于 2024-3-26 08:55
这些代码在调试模式下可以辅助理解栈,是个不错的方式。
不过生产环境不建议这么玩,因为编译优化可能导致 ...

是的,所以之前学c时老师几乎不会涉及到栈区的细节。这让我大开眼界!
 楼主| HackYike 发表于 2024-3-27 00:33
[C++] 纯文本查看 复制代码
// int 型,值为100(十进制),定位

char arr[100] = {
    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;
}
yes2 发表于 2024-3-27 08:51
[C++] 纯文本查看 复制代码
for(int k=0; k<97; k++)
{
    if (*(int*)&arr[k] == 100)
    {
        printf("%d:%d\n", k, t);
    }
}
 楼主| HackYike 发表于 2024-3-27 13:01
yes2 发表于 2024-3-27 08:51
[mw_shl_code=cpp,true]for(int k=0; k

我发出来是因为指针类型转换和解引用搅和在一起还不熟练。你这个编译不了,但我猜测似乎直接把 char[100] 当 int[25] 用了,这不符合题目要求。
 楼主| HackYike 发表于 2024-3-27 13:25
福至心灵,似乎睡了一觉有了点茅塞顿开的感觉,好像昨天困扰我好久的东西今天突然一下子就明白到底发生了什么了!!!
[C++] 纯文本查看 复制代码
#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;
}
yes2 发表于 2024-3-27 14:25
[C++] 纯文本查看 复制代码
int main()
{
    for(int k=0; k<97; k++)
    {
        if (*(int*)&arr[k] == 100)
        {
            printf("%d:%d\n", k, *(int*)&arr[k] );
        }
    }

    return 0;
}

--------------
输出:
1:100
34:100
44:100
57:100
61:100
95:100
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 14:38

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表