Created
June 12, 2021 21:46
-
-
Save cristeigabriel/82e4a070100f9aa24a2264c6d4f3a767 to your computer and use it in GitHub Desktop.
[C++] Get address to matching strings in memory bitmap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// I've also posted this on unknowncheats.me under the alias of xemacs, as noted in my GitHub description. | |
// https://www.unknowncheats.me/forum/c-and-c-/456716-address-matching-strings-memory-bitmap.html | |
// This is technically a complete implementation and ready to use, you just have to change little things to have it compliant as is right now. | |
auto c_pe::find_utf8_compare_hash( size_t hashed, bool check_8d )const->const std::vector<pattern_t> | |
{ | |
const auto &module_bitmap = get_module_bitmap( ); | |
const auto &module_text_section = grab_section_by_hash( HASH_CT( ".text" ) ); | |
auto results = std::vector<pattern_t>{}; | |
constexpr auto ptr_instruction_size = sizeof( void * ) + 1u; | |
for( auto i = module_text_section.first; i < module_text_section.second - ptr_instruction_size; ++i ) | |
{ | |
const auto ¤t_instruction = *static_cast< uint8_t * >( &module_bitmap[ i ] ); | |
const auto &next_instruction = *static_cast< uint8_t * >( &module_bitmap[ i + ptr_instruction_size ] ); | |
if( current_instruction == 0x68 /* push */ && (!check_8d || check_8d && next_instruction == 0x8D /* weed out '0x68' appearing at instruction end */ ) ) | |
{ | |
auto after_instruction_pointer_actual_address = reinterpret_cast< void * >( &module_bitmap[ i + 1 ] ); | |
if( after_instruction_pointer_actual_address ) | |
{ | |
const auto possible_text = reinterpret_cast< char ** >( after_instruction_pointer_actual_address ); | |
if( possible_text ) | |
{ | |
if( !*possible_text ) | |
{ | |
continue; | |
} | |
[ & ]( ) | |
{ | |
__try | |
{ | |
if( HASH_RT( *possible_text ) == hashed ) | |
{ | |
results.emplace_back( static_cast< address_pattern_t >( after_instruction_pointer_actual_address ) ); | |
} | |
} | |
__except( GetExceptionCode( ) == EXCEPTION_ACCESS_VIOLATION ) | |
{ | |
// just an usual day | |
return; | |
} | |
}( ); | |
} | |
} | |
} | |
} | |
return results; | |
} | |
auto pattern_t::follow_until( uint8_t instruction )const->const pattern_t | |
{ | |
auto _this = *this; | |
auto address = _this.m_address; | |
auto result = address; | |
while( *static_cast< uint8_t * >( result ) != instruction ) | |
{ | |
// nasty and probably unsafe, but here's the thing, | |
// i don't care. | |
result += 1u; | |
} | |
_this.m_address = result; | |
return _this; | |
} | |
const auto &client = g_spielo->grab_module_by_hash( HASH_CT( "client.dll" ) ); | |
// I know, gotta make a method that just returns a pattern of Nth occurence specified alone | |
const auto fps = client.find_utf8_compare_hash( HASH_CT( "fps: %5i var: %4.1f ms (v%u%s)" ) )[0]; | |
// set retaddr | |
const auto &address = fps.follow_until( 0xE8 ); | |
g_fps_net_graph_retaddr = address.get( sizeof( void * ) + 1 ); | |
// hook | |
g_spielo->steam( ).hook<format_t>( address.relative( ).get( ) ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment