简体   繁体   English

监控操作码

[英]Monitoring opcode

I am trying to monitor the assembly instructions of a functions opcode. 我正在尝试监视功能操作码的汇编指令。 I get the functions size in bytes by subtracting a stub address from the functions in memory. 我通过从内存中的函数中减去存根地址来获得函数大小(以字节为单位)。 I am currently only looking for the mov instruction. 我目前只在寻找mov指令。 When I display the currentByte, it outputs only Ú, which has a hex value of 0xDA, which is FIADD in assembly http://ref.x86asm.net/coder32.html#xDA Why does no mov instruction display? 当我显示currentByte时,它仅输出Ú,其十六进制值为0xDA,这在程序集http://ref.x86asm.net/coder32.html#xDA中为FIADD为什么没有mov指令显示?

#include <iostream>
#include <Windows.h>
#include <ctime>
#include <vector>

#define PUSH 0x50
#define POP  0x58
#define MOV  0xB8
#define NOP  0x90
#define ADD  0x01
#define AND  0x21
#define XOR  0x31
#define OR   0x09
#define SBB  0x19
#define SUB  0x29

using namespace std;

int add(int x, int y)
{
    int result;
    __asm
    {
        mov eax, x
        add eax, y
        mov result, eax
        xor eax, eax        
    }
    return result;
}

void stub() { return; }

DWORD GetFunctionSize(DWORD* functionStartAddress, DWORD* stub)
{
    DWORD dwOldProtect;
    DWORD *func, *stubAddr;

    func = (DWORD*)functionStartAddress;
    stubAddr = (DWORD*)stub;

    DWORD size = func - stubAddr;
    VirtualProtect(func, size, PAGE_EXECUTE_READWRITE, &dwOldProtect);
    return size;
}

void GetCurrentByte(PVOID function)
{
    vector<PBYTE> currByte;

    PBYTE pCurrentByte = (PBYTE)function;
    if (*pCurrentByte == MOV)
    {
        cout << "MOV instr.\n";
    }
    cout << *pCurrentByte;
    currByte.push_back(pCurrentByte);
}

int main()
{

    DWORD size = GetFunctionSize((DWORD*)&add, (DWORD*)&stub);

    for (int i = 0; i < size; i++)
    {
        GetCurrentByte(add);
    }
    system("pause");
    return 0;
}

Why does no mov instruction display? 为什么没有mov指令显示?

If you are in debugging mode, you need to know that you are passing a wrong address to the GetCurrentDate(PVOID), thats mean you are reading bytes from a wrong address and there is another few mistakes, to solve this issue follow those steps : 如果您处于调试模式,则需要知道将错误的地址传递给GetCurrentDate(PVOID),这意味着您正在从错误的地址读取字节,并且还有一些错误,要解决此问题,请按照以下步骤操作:

Firstly, the code bytes generated from : 首先,从产生的代码字节:

mov eax, x       // code bytes: 8B 45 08
mov result, eax  // code bytes: 89 45 FC 

0x8B and 0x89 are the values that you should look for inside your add(int, int) function. 0x8B和0x89是您应该在add(int,int)函数内部查找的值。

secondly, to get the address of the first byte of your add(int, int) function i suggest to use this function : 其次,要获取add(int,int)函数的第一个字节的地址,我建议使用此函数:

#define ASM_CALL                0x000000E8
#define ASM_JMP                 0x000000E9
#define ASM_CALL_SIZE           0x00000001
#define ASM_CALL_FULL_SIZE      0x00000005

DWORD GetFuncAddress(DWORD funcAddress)
{
    BYTE calledAddress = *(BYTE*)funcAddress; 

    while (calledAddress == ASM_CALL || calledAddress == ASM_JMP) {
        funcAddress = funcAddress + *(DWORD*)(funcAddress + ASM_CALL_SIZE) + ASM_CALL_FULL_SIZE;
        calledAddress = *(BYTE*)funcAddress;
    }

    return funcAddress; // The address of the first byte of the function.
}

thirdly, i suggest an optimization inside your GetFunctionSize(DOWRD), as you know that your add function ends with a single return : 第三,我建议您在GetFunctionSize(DOWRD)内进行优化,因为您知道您的add函数以单个return结尾:

return result; // code bytes: C3

why not just loop throw the bytes of the add function, so when you find a byte equivalente to 0xC3, you will end up with the exact size of your function (in bytes), this code will make things clear: 为什么不循环抛出add函数的字节,所以当您发现一个等于0xC3的字节时,最终将得到函数的确切大小(以字节为单位),此代码将使事情变得清晰:

#define ASM_RET  0xC3

SIZE_T GetFunctionSize(DWORD functionAddress)
{
    SIZE_T funcSize = 0;
    // Loop thru func's bytes, and breaks when return byte found.
    while (*((PBYTE)functionAddress++) != RET)
        funcSize++; 

    return funcSize;
}

fourthly, the GetCurrentByte(PVOID) function needs some maintenance, so i suggest : 第四,GetCurrentByte(PVOID)函数需要一些维护,所以我建议:

#define ASM_MOV1                0x8B 
#define ASM_MOV2                0x89

VOID GetCurrentByte(DWORD functionAddress, UINT &index)
{
    BYTE tempByte = *((PBYTE)functionAddress + index);
    // search for bytes which contains a mov instruction:
    if (tempByte == ASM_MOV1 || tempByte == ASM_MOV2)
        cout << "MOV instr found at : " << hex << ((DWORD)functionAddress + index) << endl;

}

finally, the full code will be like this : 最后,完整的代码将如下所示:

#include <iostream>
#include <Windows.h>


#define ASM_RET                 0xC3
#define ASM_MOV1                0x8B 
#define ASM_MOV2                0x89
#define ASM_CALL                0xE8
#define ASM_JMP                 0xE9
#define ASM_CALL_SIZE           0x01
#define ASM_CALL_FULL_SIZE      0x05

using namespace std;

INT add(INT x, INT y)
{
    int result;
    __asm
    {
        mov eax, x
        add eax, y
        mov result, eax
        xor eax, eax
    }
    return result;
}

DWORD GetFuncAddress(DWORD funcAddress)
{
    BYTE calledAddress = *(BYTE*)funcAddress;

    while (calledAddress == ASM_CALL || calledAddress == ASM_JMP) {
        funcAddress = funcAddress + *(DWORD*)(funcAddress + ASM_CALL_SIZE) + ASM_CALL_FULL_SIZE;
        calledAddress = *(BYTE*)funcAddress;
    }

    return funcAddress;
}

SIZE_T GetFunctionSize(DWORD functionAddress)
{
    SIZE_T funcSize = 0;

    while (*((PBYTE)functionAddress++) != ASM_RET)
    {
        funcSize++; 
    }

    return funcSize;
}


VOID GetCurrentByte(DWORD functionAddress, UINT &index)
{
    BYTE tempByte = *((PBYTE)functionAddress + index);

    if (tempByte == ASM_MOV1 || tempByte == ASM_MOV2)
        cout << "MOV instr found at : " << hex << ((DWORD)functionAddress + index) << endl;

}


INT main()
{

    DWORD funcAddress = GetFuncAddress((DWORD)add); // Get func address.

    SIZE_T size = GetFunctionSize(funcAddress); // Get func size (bytes).

    for (UINT i = 0; i < size; i++) // loop thru the function memory block.
    {
        GetCurrentByte(funcAddress, i);
    }


    system("pause");
    return 0;
}

Don't be surprised if you found many MOV instructions in your function because the compiler created them. 如果在函数中发现许多MOV指令,请不要感到惊讶,因为编译器已创建了它们。

Amrane Abdelkader. Amrane Abdelkader。

GetCurrentByte() looks at the first byte every time you call it. 每次调用GetCurrentByte()时,它都会查看第一个字节。 Looking at the first byte size times doesn't help you. 查看第一个字节的size时间对您没有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM