【问题标题】:C++ Signature Scanner output wrongC++ 签名扫描程序输出错误
【发布时间】:2014-02-28 01:35:35
【问题描述】:

我正在用 c++ 制作签名扫描器,为了测试它,我将注入到 steam 中并比较前 10 个字节。

#define sig "\x4D\x5A\x90\x00\x03\x00\x00\x00\x04\x00\x00"

当我到达第 3 个字节 x90 时,我得到的输出是:

steam: \x4D\x5A\x90\x00\x03\x00\x00\x00\x04\x00\x00
sig: \x4D\x5A\xFFFFFF90\x00\x03\x00\x00\x00\x04\x00\x00

这是我的全部来源:

#include <Windows.h>
#include <stdio.h>
#include <Psapi.h>
#define sig "\x4D\x5A\x90\x00\x03\x00\x00\x00\x04\x00"

#pragma comment( lib, "Psapi" )

HANDLE thread = NULL;

DWORD getImageSize( MEMORY_BASIC_INFORMATION &memInfo )
{
if( !VirtualQuery( GetModuleHandleA(NULL), &memInfo, sizeof( memInfo ) ) )
    return 0x00;

IMAGE_DOS_HEADER *dosHeader     = (IMAGE_DOS_HEADER *)memInfo.AllocationBase;
IMAGE_NT_HEADERS *peHeader      = (IMAGE_NT_HEADERS *)((unsigned long)dosHeader + (unsigned long)dosHeader->e_lfanew);

if( peHeader->Signature != IMAGE_NT_SIGNATURE )
    return 0x00;

return peHeader->OptionalHeader.SizeOfImage;
}

DWORD scan( HANDLE hProc, const DWORD length = 0x200, DWORD base = 0x00 )
{   
  if(!base )
    return base;

if( AllocConsole() )
    AttachConsole( GetCurrentProcessId() );

freopen( "CON", "w", stdout );

SetConsoleTitleW( L"Test Console" );

MEMORY_BASIC_INFORMATION memInfo;
int sigLength = sizeof( sig );

const DWORD size = getImageSize( memInfo );
unsigned char *pBase;
pBase = (unsigned char *)base;

printf( "Size = %d\n", size );

if( !size )
    return size;

for( int i(0); i < size; i++ )
{
    printf( "\\x%02X", pBase[i] );
    printf( "\\x%02X", (unsigned char *)sig[i] );

    if( i && (i % 10 == 0))
        system( "PAUSE" );

    if( pBase[i] == sig[i] )
    {
        for( int j(i), k(0); k < sigLength; j++, k++ )
        {
            if( sig[k] == '?' )
                continue;

            if( pBase[j] != sig[k] )
                break;

            if( j == (sigLength-1) )
                return (DWORD)&pBase[i];
        }
    }
}

printf( "\n" );

system( "PAUSE" );

return 0x00;
}

BOOL WINAPI DllMain ( HMODULE hModule, DWORD dwReason, LPVOID lpReserved )
{
if( dwReason == DLL_PROCESS_ATTACH )
{
    DWORD base = (DWORD)GetModuleHandleA( NULL );
    scan( GetCurrentProcess(), 0x200, base );
}

return TRUE;
}

我能想到的唯一一件事是该值被视为已签名,但 %02X 不会使其未签名吗?

提前致谢。

【问题讨论】:

    标签: c++ hex


    【解决方案1】:

    格式说明符%02X 表示使用大写十六进制字母打印值。与签名或未签名无关。

    如果你想要无符号,你可以使用参数hhh,如printf format specifiers.

    我个人会在对 {f}printf 的调用中将参数转换为无符号。

    【讨论】:

    • 其实%X%x%o%u都假设传递的值是无符号整数类型。但是,char 值在传递给 printf() 时会经历“常规转换”并最终成为 int,如果 char 类型是有符号的,则 0x80..0xFF 中的值最终可能会成为负整数。但是,您将角色转换为 unsigned char 的建议(假设这就是您的意思)是正确的。在 C99 中添加了 hh 修饰符;它可能在 Windows 上不可用。我需要检查 C89 中 printf() 上的 h 修饰符,但我不会惊讶地发现它也在 C99 中添加。 MSVC 是 C89。
    • 我的意思是在 '%02X' 中以 '0' 为前缀,而不是 X 表示无符号。哦,天哪,我怎么错过了?我已经尝试过类型转换,但我正在转换为 (unsigned char *) 而不是 (unsigned char) 哈哈,谢谢你们的帮助——它奏效了 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-02
    相关资源
    最近更新 更多