Skip to main content
GameDev.net gamedev.net
🔒 Locked

How to get the addr of code buff in x64 platform!

Started by laiyierjiangsu Jun 27, 2017 at 12:30 PM 10 replies 2.5k views
Original Post
laiyierjiangsu
laiyierjiangsu


As the following picture shows , I can get the code buff with asm in x86 platform. Has anyone know how to do this in x64 platform???



bool CheckCodeSnipeCrc32()
{
	DWORD addr1, addr2, size;
	_asm mov addr1, offset codeBegin;
	_asm mov addr2, offset codeEnd;
	codeBegin:
		//OutputDebugString(L"test");
		//OutputDebugString(L"test0");
		//OutputDebugString(L"test1");
		int a = 0;
		a = a + 1;
		a = a - 1;
	codeEnd:
		size = addr2 - addr1;
		DWORD curcrc32 = Crc32_ComputeBuf((void*)addr1, size);
		DWORD oldCrc32 = 0xbcf07446;
		assert(oldCrc32 == curcrc32);
}


Stay hungry, stay foolish!
Lactose
Lactose

There is no picture.

EDIT: It's edited in now, ignore my original post :)

Hello to all my stalkers.
laiyierjiangsu
laiyierjiangsu
1 hour ago, Lactose said:

There is no picture.

Edit: Some code has now been edited in. This post can be ignored :)

Why? I have pasted the code screenshot, but it didn't show. So I add the code here!

Stay hungry, stay foolish!
Lactose
Lactose
Just now, laiyierjiangsu said:

Why? I have pasted the code screenshot, but it didn't show. So I add the code here!

I mean my post could be ignored, since you edited it it. Sorry for the confusion :)

Hello to all my stalkers.
Khatharr
Khatharr

VS doesn't support inline assembly in x64 builds.

For CRC checking a function body... Hmm...

Let me fiddle with it for a minute.


No, I can't come up with anything reliable. Even trying to grab the function pointer as a starting point I ended up staring at a jump table.

void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.
Nypyren
Nypyren
21 minutes ago, Khatharr said:

Even trying to grab the function pointer as a starting point I ended up staring at a jump table.

Do you have edit-and-continue turned on and you're looking at the JMP thunk?

Khatharr
Khatharr

Probably.
You'd also have to prevent inlining if it was done that way, and there's still the problem of finding the end address of the function.

The other thing that I was looking at was getting label addresses, but apparently that's not a thing (though gcc may offer it).

I guess one other option may be to just write your own sort of sub-loader. You could dump the module memory from a loaded/running version, then load that into an x-flagged page at runtime and jump in. You'd need to have some jumpout for CRC checking, though, and that would have to be a static address somehow because otherwise it would change the CRC of the module, though I suppose it wouldn't be too hard to compensate for that if you have the address as zero in the file and then when you load it you set it to the target address and then add that value to the checksum.

Still, though, if I were hacking that game I'd just overwrite the CRC function to indicate success.

void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.
laiyierjiangsu
laiyierjiangsu
11 hours ago, Lactose said:

I mean my post could be ignored, since you edited it it. Sorry for the confusion :)

Thanks , Lactose ! My English is poor, xD

Stay hungry, stay foolish!
laiyierjiangsu
laiyierjiangsu
4 hours ago, Khatharr said:

Probably.
You'd also have to prevent inlining if it was done that way, and there's still the problem of finding the end address of the function.

The other thing that I was looking at was getting label addresses, but apparently that's not a thing (though gcc may offer it).

I guess one other option may be to just write your own sort of sub-loader. You could dump the module memory from a loaded/running version, then load that into an x-flagged page at runtime and jump in. You'd need to have some jumpout for CRC checking, though, and that would have to be a static address somehow because otherwise it would change the CRC of the module, though I suppose it wouldn't be too hard to compensate for that if you have the address as zero in the file and then when you load it you set it to the target address and then add that value to the checksum.

Still, though, if I were hacking that game I'd just overwrite the CRC function to indicate success.

Thanks, I just use this methed to detect that if my core code is being debugging . If someone wants to hack , it's achieveable.

Stay hungry, stay foolish!
frob
frob
58 minutes ago, laiyierjiangsu said:

I just use this methed to detect that if my core code is being debugging . If someone wants to hack , it's achieveable.

If you're looking for informational reasons, or for code to take special paths, most operating systems have code that politely indicates if a debugger is attached. On windows those are IsDebuggerPresent() to see if the program was launched by a debugger, and CheckRemoteDebuggerPresent().

The programs are always hackable, and it is possible to attach debuggers without those flags getting set, but they can serve as good tools if you want to use different behavior while being debugged.

ApochPiQ
ApochPiQ

You can (ab)use the _ReturnAddress intrinsic if you're building with Visual Studio... but I don't think it gets you what you want, at least not directly.

The problem in general (as I understand it) is that your original source code may not look like the actual generated machine code. For example, any of the following can make your code look different in disassembly than it does in the original source:

  • Inlined functions
  • Outlined functions (rarer but still happens)
  • Loop unrolling
  • Vectorization
  • Dead code elimination
  • Optimizations that try to maximize code locality
  • etc.

Because of this, generating a couple of labels in source and pulling their addresses may actually produce inconsistent or unpredictable results. It's actually pretty hard to know if your original source sufficiently resembles your machine code to do tricks like you're doing with the x86 assembly thing.

If you've ever stepped through an optimized program you've probably noticed that the current statement jumps around in weird ways; this is an indicator that the machine code is not 100% mimicking the source code - and that's a good thing. It means the optimizer is doing its job. Unfortunately, it also means that tricks to detect weirdness in the machine code have to be based on the machine code itself, not on the source-level code.

A common tactic is to use debug metadata (e.g. PDB files or DWARF on Unixy platforms) to statically analyze your compiled program, and generate CRCs or other sanity checks that can be embedded back into the program without recompiling it. Depending on what your needs are and how patient you are with doing weird linker hacks, that may or may not be a suitable approach here.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.