Thread: AOB SCAN

Results 1 to 5 of 5
  1. #1
    leacherxd's Avatar
    Join Date
    Jan 2017
    Gender
    male
    Posts
    128
    Reputation
    55
    Thanks
    20

    AOB SCAN

    So I'm hacking this game called Brawlhalla and after about 30hrs of not being able to locate the base address of modules to access the values of certain multilevel pointers -- I decided to just use an AOB scan to get the playerclass.
    I found this specific string
    (00 00 00 00 00 00 00 00 00 00 00 00 00 00 0E 40 1F 85 EB 51 B8 9E 16 40 00 00 00 00 00 00 39 40 9A 99 99 99 99 99 E9 3F)
    that when plugged into cheat engine Array of Byte scan gives me an address which is always by the playerclass-- so I can add however many bytes I need forward to get different values.

    So I understand that I can do this in cheat engine and even in the Auto Assembly Script creator.

    But I want to do more complex operations with these values and thus want to integrate an AOB scan into an external cpp application. I have looked at several implementations on the internet and they haven't worked for various reasons which are not exactly easy to look up, but if they arise again in any of your guys' implementations, you will be able to help me much more effectively. It's probably because I'm not getting the base address of the module properly, but I still would like to have and understand a source code for an external (or internal, I've just had less luck with that) aob scan.

    If anyone could give me any tips or a source for this specific purpose I would appreciate it hugely. I've been trying very, very hard to break into the game-hacking scene via hacking Brawlhalla and it's incredibly fun. I will give back to this community what I have learned from it, but I really need some help in this thread.

    Thank you to everyone who replies

    Update: I have determined that it must be an issue with hooking into Brawlhalla with C++.

    Code:
    MODULEINFO GetModuleInfo(char *szModule)
    {
    	MODULEINFO modinfo = { 0 };
    	HMODULE hModule = GetModuleHandle(szModule);
    	if (hModule == 0)
    		return modinfo;
    	GetModuleInformation(GetCurrentProcess(), hModule, &modinfo, sizeof(MODULEINFO));
    	return modinfo;
    }
    
    DWORD FindPattern(char *module, char *pattern, char *mask)
    {
    	//Get all module related information
    	MODULEINFO mInfo = GetModuleInfo(module);
    
    	//Assign our base and module size
    	DWORD base = (DWORD)mInfo.lpBaseOfDll;
    	DWORD size = (DWORD)mInfo.SizeOfImage;
    
    	//Get length for our mask, this will allow us to loop through our array
    	DWORD patternLength = (DWORD)strlen(mask);
    
    	for (DWORD i = 0; i < size - patternLength; i++)
    	{
    		bool found = true;
    		for (DWORD j = 0; j < patternLength; j++)
    		{
    			//if we have a ? in our mask then we have true by default,
    			//or if the bytes match then we keep searching until finding it or not
    			found &= mask[j] == '?' || pattern[j] == *(char*)(base + i + j);
    		}
    
    		//found = true, our entire pattern was found
    		if (found)
    		{
    			return base + i;
    		}
    	}
    	return NULL;
    }
    Using that code,
    Code:
    DWORD dmgAddy = FindPattern("Brawlhalla.exe", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x  00\x00\x0E\x40\x1F\x85\xEB\x51\xB8\x9E\x16\x40\x00  \x00\x00\x00\x00\x00\x39\x40\x9A\x99\x99\x99\x99\x  99\xE9\x3F", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
    returns 0

    While in cheat engine, it works. So it's not hooking into brawlhalla correctly.
    Even when I replace "Brawlhalla.exe" with "Adobe AIR.dll" (another module in the memory) it doesn't work. What module do I use? How do I know where to scan? I followed Fleep's tutorial on youtube exactly.

    (that is, this one)


    Again, thank you guys very much!!!!

  2. #2
    leacherxd's Avatar
    Join Date
    Jan 2017
    Gender
    male
    Posts
    128
    Reputation
    55
    Thanks
    20


    I replaced the 0's with ?'s in the mask and in Cheat Engine. It works in Cheat Engine, but not in my DLL.
    Code:
    DWORD dmgAddy = FindPattern("Brawlhalla.exe", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x  00\x00\x0E\x40\x1F\x85\xEB\x51\xB8\x9E\x16\x40\x00  \x00\x00\x00\x00\x00\x39\x40\x9A\x99\x99\x99\x99\x  99\xE9\x3F", "??????????????xxxxxxxxxx??????xxxxxxxxxx");

    UPDATE:
    So I'm sorry for rushing into this without much of a basic knowledge of modules and their base addresses.
    When telling the program to return the base module address it returns this:

    which lines up with cheat engine. This is where the memory starts.


    So it hooks into brawlhalla correctly. Why does FindPattern always return 0x0?

  3. #3
    MikeRohsoft's Avatar
    Join Date
    May 2013
    Gender
    male
    Location
    Los Santos
    Posts
    797
    Reputation
    593
    Thanks
    26,314
    are you part of the process or you try it from an external application?

  4. #4
    leacherxd's Avatar
    Join Date
    Jan 2017
    Gender
    male
    Posts
    128
    Reputation
    55
    Thanks
    20
    Quote Originally Posted by MikeRohsoft View Post
    are you part of the process or you try it from an external application?
    I'm doing this with a DLL, so internal and part of the process.
    I'm pretty sure the only difference is that Cheat Engine scans from base address to max address, and selecting Brawlhalla as my module and using
    Code:
    DWORD size = (DWORD)mInfo.SizeOfImage;
    doesn't actually go to max address.
    Any ideas..?

    Thank you very much, I think I'm near the end of this milestone which would open up to really being able to interact with the application through c++ (something I've been trying to do for weeks)

  5. #5
    MikeRohsoft's Avatar
    Join Date
    May 2013
    Gender
    male
    Location
    Los Santos
    Posts
    797
    Reputation
    593
    Thanks
    26,314
    Code:
    bool isHex(char c)
    {
    	return (c >= 48 && c <= 57) || (c >= 65 && c <= 90) || (c >= 97 && c <= 122);
    }
    
    bool createPattern(const std::string& pattern, std::string& pattern_result, std::string& mask_result)
    {
    	bool result = false;
    	size_t l = pattern.size();
    	if (l-- > 0)
    	{
    		std::stringstream pattern_s;
    		std::stringstream mask_s;
    		for (size_t i = 0; i < l; i++)
    		{
    			if (!isHex(pattern[i]))
    			{
    				if (pattern[i] == 63)
    				{
    					pattern_s << "\x90";
    					mask_s << '?';
    				}
    			}
    			else
    			{
    				char buffer[2];
    				buffer[0] = pattern[i];
    				buffer[1] = (l >= i + 1 && isHex(pattern[i + 1])) ? pattern[++i] : 0;
    				pattern_s << (char)strtol(buffer, nullptr, 16);
    				mask_s << 'x';
    			}
    		}
    		result = true;
    		pattern_result = pattern_s.str();
    		mask_result = mask_s.str();
    	}
    	return result;
    }
    
    uint64_t getImageSize(uint64_t moduleBase)
    {
    	const IMAGE_DOS_HEADER*	headerDos = (const IMAGE_DOS_HEADER*)moduleBase;
    	const IMAGE_NT_HEADERS*	headerNt = (const IMAGE_NT_HEADERS64*)((const unsigned char*)headerDos + headerDos->e_lfanew);
    	return (uint64_t)moduleBase + headerNt->OptionalHeader.SizeOfCode;
    }
    
    char* ptrScan(const std::string& pattern, const std::string& mask, int find)
    {
    	uint64_t base = (uint64_t)GetModuleHandleA(nullptr);
    	char* ptr = (char*)base;
    	char* end = (char*)getImageSize(base);
    	size_t matchlen = mask.size();
    	for (int i = 0, found = 0; ptr != end; ptr++)
    	{
    		if (*ptr == pattern[i] || mask[i] == 63)
    		{
    			if (++i == matchlen)
    			{
    				if (find != found)
    				{
    					i = 0;
    					found++;
    				}
    				else
    				{
    					ptr -= matchlen - 1;
    					break;
    				}
    			}
    		}
            }
            else if (i > 0 && (*ptr == pattern[0] || *ptr == mask[0])) 
            {
                i = 1;
            }
    		else
            {
                i = 0;
            }
    			
    	}
    	if (ptr == end)
    		return nullptr;
    	return ptr;
    }
    
    char* ptrScan(const std::string& pattern, int find)
    {
    	std::string sub_ptr;
    	std::string sub_mask;
    	createPattern(pattern, sub_ptr, sub_mask);
    	return ptrScan(sub_ptr, sub_mask, find);
    }
    Code:
    const char* = ptrScan("? ? ? ? ? ? ? ? ? ? ? ? ? ? 0E 40 1F 85 EB 51 B8 9E 16 40? ? ? ? ? ? 39 40 9A 99 99 99 99 99 E9 3F");
    Last edited by MikeRohsoft; 06-25-2019 at 12:16 AM.

Similar Threads

  1. Updating AOB scan codes..
    By Warframe. in forum General Game Hacking
    Replies: 0
    Last Post: 08-03-2013, 05:33 PM
  2. [Help] C++ Aob Scanning
    By drlunar in forum C++/C Programming
    Replies: 2
    Last Post: 10-29-2012, 11:04 PM
  3. [Help] AOB Scanning
    By drlunar in forum C++/C Programming
    Replies: 2
    Last Post: 07-18-2012, 01:11 AM
  4. Introduction to Updating Auto Assembly Scripts (AOB Scan)
    By Blitz in forum Game Hacking Tutorials
    Replies: 4
    Last Post: 04-28-2011, 12:23 AM
  5. AoB Scan
    By Sintax1 in forum C++/C Programming
    Replies: 5
    Last Post: 03-31-2011, 09:36 PM