@@ -42,7 +42,7 @@ HANDLE Process::get_handle(const std::string &name) {
4242
4343 debug (" %s '%s' %s %lu" , " found process" , name.c_str (), " with id" , process_id);
4444
45- HANDLE handle = OpenProcess (PROCESS_VM_READ, FALSE , process_id);
45+ HANDLE handle = OpenProcess (PROCESS_VM_READ | PROCESS_QUERY_INFORMATION , FALSE , process_id);
4646 if (!handle || handle == INVALID_HANDLE_VALUE) {
4747 throw std::runtime_error (" failed opening handle to process" );
4848 }
@@ -53,53 +53,79 @@ HANDLE Process::get_handle(const std::string &name) {
5353}
5454
5555uintptr_t Process::find_pattern (const char *pattern) {
56- auto pattern_bytes = std::vector<int >{ };
57-
58- for (auto cur = pattern; *cur; cur++) {
59- if (*cur == ' ?' ) {
60- // If the current byte is a wildcard push a dummy byte
61- pattern_bytes.push_back (-1 );
62- } else if (*cur == ' ' ) {
63- continue ;
64- } else {
65- // This is somewhat hacky: strtol parses *as many characters as
66- // possible* and sets cur to the first character it couldn't parse.
67- // This is the reason why patterns *must* follow the structure
68- // "AB CD EF ? ? FF"; "ABCDEF??FF" would cause it to fail later (!).
69- pattern_bytes.push_back (strtol (cur, const_cast <char **>(&cur), 16 ));
70- }
71- }
56+ const auto pattern_to_bytes = [](const char *pattern) {
57+ auto pattern_bytes = std::vector<int >{ };
7258
73- auto pattern_size = pattern_bytes.size ();
59+ for (auto cur = pattern; *cur; cur++) {
60+ if (*cur == ' ?' ) {
61+ // If the current byte is a wildcard push a dummy byte
62+ pattern_bytes.push_back (-1 );
63+ } else if (*cur == ' ' ) {
64+ continue ;
65+ } else {
66+ // This is somewhat hacky: strtol parses *as many characters as
67+ // possible* and sets cur to the first character it couldn't parse.
68+ // This is the reason why patterns *must* follow the structure
69+ // "AB CD EF ? ? FF"; "ABCDEF??FF" would cause it to fail later (!).
70+ pattern_bytes.push_back (strtol (cur, const_cast <char **>(&cur), 16 ));
71+ }
72+ }
7473
75- const size_t chunk_size = 4096 ;
76- std::byte chunk_bytes[chunk_size] ;
74+ return pattern_bytes ;
75+ } ;
7776
78- for (uintptr_t i = 1 ; i < INT_MAX; i += chunk_size - pattern_size) {
79- if (!read_memory<std::byte>(i, chunk_bytes, chunk_size)) {
80- continue ;
81- }
77+ const auto pattern_bytes = pattern_to_bytes (pattern);
78+ const auto pattern_size = pattern_bytes.size ();
79+
80+ uintptr_t cur_address = 0 ;
81+ // this is an osu-specific optimization
82+ uintptr_t max_address = 0x7fffffff ;
83+
84+ while (cur_address < max_address) {
85+ MEMORY_BASIC_INFORMATION info;
86+
87+ if (!VirtualQueryEx (handle, reinterpret_cast <void *>(cur_address), &info, sizeof (info))) {
88+ debug (" couldn't query at %x" , cur_address);
89+
90+ return 0 ;
91+ }
8292
83- for (size_t j = 0 ; j < chunk_size; j++) {
93+ bool invalidType = (info.Type != MEM_IMAGE && info.Type != MEM_PRIVATE);
94+ bool invalidProtection = (info.Protect != PAGE_WRITECOPY && info.Protect != PAGE_EXECUTE_WRITECOPY
95+ && info.Protect != PAGE_EXECUTE_READWRITE && info.Protect != PAGE_READWRITE);
96+
97+ if (info.RegionSize == 0 || info.State != MEM_COMMIT || invalidType || invalidProtection) {
98+ cur_address = reinterpret_cast <uintptr_t >(info.BaseAddress ) + info.RegionSize ;
99+
100+ continue ;
101+ }
102+
103+ cur_address = reinterpret_cast <uintptr_t >(info.BaseAddress );
104+
105+ auto buffer = std::vector<std::byte>(info.RegionSize );
106+ read_memory<std::byte>(cur_address, buffer.data (), buffer.size ());
107+
108+ for (size_t j = 0 ; j < buffer.size (); j++) {
84109 bool hit = true ;
85110
86111 for (size_t k = 0 ; k < pattern_size; k++) {
87112 if (pattern_bytes[k] == -1 ) {
88113 continue ;
89114 }
90115
91- if (chunk_bytes[j + k] !=
92- static_cast <std::byte>(pattern_bytes[k])) {
116+ if (buffer.at (j + k) != static_cast <std::byte>(pattern_bytes[k])) {
93117 hit = false ;
94118 break ;
95119 }
96120 }
97121
98122 if (hit) {
99- return i + j;
123+ return cur_address + j;
100124 }
101125 }
102- }
126+
127+ cur_address += info.RegionSize ;
128+ }
103129
104130 return 0 ;
105131}
0 commit comments