【问题标题】:How can I edit a value stored at an address through C++?如何通过 C++ 编辑存储在地址中的值?
【发布时间】:2015-02-28 23:19:51
【问题描述】:

我需要能够编辑存储在 ECX 和 EAX 寄存器中的两个地址所指向的两个内存区域。

我通过在客户端原始可执行文件中放置一个 Code Cave 来执行此操作,该可执行文件会跳转到我的 Prepare_Encrypt() 函数。

我的总体想法是 Prepare_Encrypt() 将获取地址,并且应该能够以某种方式使用它们在 C++ 中创建指向数据的指针。

创建指针后,我将创建一个 For 循环,该循环将对指针中的每个字符值执行 XOR 操作。

我是使用内联汇编的新手,所以我真的很想按照我想要的方式工作。

我认为创建一个 char* 并使用 MOV 操作会起作用,但事实并非如此。有没有人知道如何让它发挥作用?

这是我当前的 Prepare_Encrypt() 函数和我当前的 Encrypt() 函数。

DWORD_PTR* data1_address = NULL;
DWORD_PTR* data2_address = NULL;

void Encrypt()
{
    // Somehow create a pointer to the memory location at the address stored in data1_address & data2_address. Something like this...
    //char* data1_pointer = CreatePointerFromAddress(data1_address);
    //char* data2_pointer = CreatePointerFromAddress(data2_address);

    for(var i = 0; i < sizeof(data1_pointer); i++)
    {
        data1_pointer[i] ^= 200;
    }

    for(var i = 0; i < sizeof(data2_pointer); i++)
    {
        data2_pointer[i] ^= 125;
    }
}

_declspec(naked) void Prepare_Encrypt()
{
    // Save program state.
    __asm
    {
        MOV ECX, ESI
        MOV DWORD PTR SS : [ESP+0x1C], EAX
        PUSHAD
        PUSHFD

        // Get Current Data From Memory
        MOV data1_address, ECX
        MOV data2_address, EAX
    }

    Encrypt();

    // Restore the program state and return to original code.
    __asm
    {
        POPFD
        POPAD
        JMP SendJMPTo
    }
}

【问题讨论】:

  • 您的代码用ESI 覆盖ECX 并用EAX 覆盖堆栈槽...这是故意的吗?
  • 是的,这是我添加代码洞穴时被覆盖的代码,因此需要将其添加到代码洞穴中。
  • 您要更改EAXECX 指向的内存还是要更改指针本身?在前一种情况下,sizeof() 不起作用,因为它给出了指针的大小,而在后一种情况下,您当然会通过恢复原始寄存器来丢弃解密的值。
  • 我想改变EAX和ECX指向的内存。是的,我知道 sizeof 将不起作用,因为它被赋予了地址而不是内容。这正是我的问题。我不知道如何获取该地址处的数据并将其分配给指针。我已经编辑了我的代码,以便变得更加清晰......
  • 你存储指针没问题,只是sizeof 不行。原样的代码应该解密两个内存区域的前 4 个字节。您需要知道自己解密的长度。怎么不行?

标签: c++ assembly x86 inline-assembly


【解决方案1】:

如果你想对它们做一些事情,你需要知道这两个数组的大小。

要么使用全局变量(即.data 部分),要么将它们作为参数推送到Encrpyt()

类似的东西:

#include "stdio.h"

void* pdata1 = NULL;
void* pdata2 = NULL;
size_t size_data1 = 0;
size_t size_data2 = 0;

/* test stuff */

void* test1 = NULL;
void* test2 = NULL;

void test(){
    test1 = malloc(0x100);
    memset(test1, 0x41, 0x100);
    test2 = malloc(0x100);
    memset(test2, 0x43, 0x100);
}

/* end test stuff*/

void Encrypt() {
    for (int i = 0; i < size_data1; ++i) {
        ((char*)(pdata1))[i] ^= 0x42;
    }

    for (int i = 0; i < size_data2; ++i) {
        ((char*)(pdata2))[i] ^= 0x42;
    }
}


_declspec(naked) void Prepare_Encrypt() {
    __asm{
            ; test stuff
            mov ecx, test1
            mov eax, test2
            ; end test

            pushad
            pushfd

            ; set pointers
            mov pdata1, ecx
            mov pdata2, eax

            ; set sizes
            mov size_data1, 100h
            mov size_data2, 100h

    }

    Encrypt();

    __asm {
        popfd
        popad

        ;.... return somewhere
        ret
    }

}

int main(int argc, char *argv[])
{

    test();

    Prepare_Encrypt();

    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-13
    • 1970-01-01
    • 1970-01-01
    • 2019-07-15
    • 1970-01-01
    • 1970-01-01
    • 2016-06-12
    • 1970-01-01
    相关资源
    最近更新 更多