Skip to content

Instantly share code, notes, and snippets.

@cristeigabriel
Created June 12, 2021 21:46
Show Gist options
  • Save cristeigabriel/82e4a070100f9aa24a2264c6d4f3a767 to your computer and use it in GitHub Desktop.
Save cristeigabriel/82e4a070100f9aa24a2264c6d4f3a767 to your computer and use it in GitHub Desktop.
[C++] Get address to matching strings in memory bitmap
// 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 &current_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