-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathscan.cpp
93 lines (73 loc) · 2.44 KB
/
scan.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include "scan.hpp"
#include "print.hpp"
#define IS_IN_RANGE( value, max, min ) ( value >= max && value <= min )
#define GET_BITS( value ) ( IS_IN_RANGE( value, '0', '9' ) ? ( value - '0' ) : ( ( value & ( ~0x20 ) ) - 'A' + 0xA ) )
#define GET_BYTE( value ) ( GET_BITS( value[0] ) << 4 | GET_BITS( value[1] ) )
namespace Horizon::Memory
{
std::uintptr_t Scan( const std::string& image_name, const std::string& signature )
{
auto image = GetModuleHandleA( image_name.c_str() );
if( !image )
{
#ifdef DEBUG
Win32::Error( "GetModuleHandleA failed (L3D451R7::Memory::%s)", __FUNCTION__ );
#endif // DEBUG
return 0u;
}
auto image_base = ( std::uintptr_t )( image );
auto image_dos_hdr = ( IMAGE_DOS_HEADER* )( image_base );
if( image_dos_hdr->e_magic != IMAGE_DOS_SIGNATURE )
{
#ifdef DEBUG
Win32::Error( "IMAGE_DOS_HEADER::e_magic is invalid (L3D451R7::Memory::%s)", __FUNCTION__ );
#endif // DEBUG
return 0u;
}
auto image_nt_hdrs = ( IMAGE_NT_HEADERS* )( image_base + image_dos_hdr->e_lfanew );
if( image_nt_hdrs->Signature != IMAGE_NT_SIGNATURE )
{
#ifdef DEBUG
Win32::Error( "IMAGE_NT_HEADERS::Signature is invalid (L3D451R7::Memory::%s)", __FUNCTION__ );
#endif // DEBUG
return 0u;
}
auto scan_begin = ( std::uint8_t* )( image_base );
auto scan_end = ( std::uint8_t* )( image_base + image_nt_hdrs->OptionalHeader.SizeOfImage );
std::uint8_t* scan_result = nullptr;
std::uint8_t* scan_data = ( std::uint8_t* )( signature.c_str() );
for( auto current = scan_begin; current < scan_end; current++ )
{
if( *( std::uint8_t* )scan_data == '\?' || *current == GET_BYTE( scan_data ) )
{
if( !scan_result )
scan_result = current;
if( !scan_data[2] )
return ( std::uintptr_t )( scan_result );
scan_data += ( *( std::uint16_t* )scan_data == '\?\?' || *( std::uint8_t* )scan_data != '\?' ) ? 3 : 2;
if( !*scan_data )
return ( std::uintptr_t )( scan_result );
}
else if( scan_result )
{
current = scan_result;
scan_data = ( std::uint8_t* )( signature.c_str() );
scan_result = nullptr;
}
}
#ifdef DEBUG
Win32::Warning( "Signature '%s' in module '%s' not found (L3D451R7::Memory::%s)", signature.c_str(), image_name.c_str(), __FUNCTION__ );
#endif // DEBUG
return 0u;
}
DWORD follow_rel32(DWORD addr, size_t offset)
{
if (!addr)
return NULL;
auto offsetAddr = addr + offset;
auto relative = *(uint32_t*)(offsetAddr);
if (!relative)
return NULL;
return (DWORD)(offsetAddr + relative + sizeof(uint32_t));
}
}