Im trying to get the engine version of a game from a global pointer, but I am fairly new to this. Here is a very small example I found...
http://ampaste.net/mb42243
And this is the disassembly for what I am trying to get, the pointer (gpszVersionString) is the highlighted line (line 5)
http://ampaste.net/m2a8f8887
So what I need to find out is basically using the example approach I found to get it, would I need to basically sig out the first part of the function and find the offset to that line?
Like...
Memory signature - /x56/x8B/x35/x74/xD5/x29/x10/x68/x00/xA8/x38/x10
Then an offset to reach that line? (not sure how to find the offset)
You can't directly do this. Process address space is completely unique to your process -- 0xDEADBEEF can point to "Dog" in one process, while 0xDEADBEEF can point to "Cat" in another. You would have to make operating system calls that allow you to access another process' address space, and even then you'd have to guess. Many times that location will be different each run of the application -- you can't generally predict what the runtime layout of a process will be in all cases.
Assuming you're on Windows you'll need to (EDIT: You don't need A and B in all cases but you usually need them) A. be an administrator, B. take the SeDebugPrivilege for your process, C, open a handle to the process, and then D. use ReadProcessMemory/WriteProcessMemory to do what you want.
Hope that helps :)
EDIT 2: It looks like you're looking at an address taken from a disassembler. If that's the case, then you can't use that value of the address -- the image can be re-based at runtime and the value there would be completely different. Particularly on recent versions of Windows which support Address Space Layout Randomization.
Related
I need to get the stacktrace programatically in a c++/winrt program (not only on crashes). The APIs are very limited for this (no dbghlp for example), but I found a way to get the virtual addresses in the running process (from the assembly code here).
From here I would like to find the function names. If I generate a MAP file can I get the address of my function (RVO + Preferred base), and if I compare it to the address in runtime I always get a diff of
0x009e0000
I have no idea from where this diff comes and if I can always count on finding the function by subtracting this number, so I would like to know how to calculate it.
There is a function in this program, that currently returns a 1. I would prefer for it to return a 0.
uregs[R_PC] is the program counter.
arg0 is the program counter offset from where we left the function (assembly, "ret").
From this I deduce: we can add the offset to the program counter, uregs[R_PC]+arg0, to find the address of the return value.
I have allocated a 32-bit "0", and I try to write 2 bytes of it into the address where the return value lives (our function expects to return a BOOL16, so we only need 2 bytes of 0):
sudo dtrace -p "$(getpid)" -w -n '
int *zero;
BEGIN { zero=alloca(4); *zero=0; }
pid$target::TextOutA:return {
copyout(zero, uregs[R_PC]+arg0, 2);
}'
Of course I get:
dtrace: error on enabled probe ID 2 (ID 320426: pid60498:gdi32.dll.so:TextOutA:return): invalid address (0x41f21c) in action #1 at DIF offset 60
uregs[R_PC] is presumably a userspace address. Probably copyout() wants a kernel address.
How do I translate the userspace address uregs[R_PC] to kernel-space? I know that with copyin() we can read data stored at user-space address, into kernel-space. But that doesn't give us the kernel address of that memory.
Alternatively: is there some other way to change the return value using DTrace?
DTrace is not the right tool for this. You should instead use a debugger like dbx, mdb or gdb.
In the meantime, I'll try to clarify some of the concepts that you've mentioned.
To begin, you may well see in the source code for a simple function that there is a single return. It is quite possible that the compiled result, i.e. the function's machine-specific implementation, also contains only a single point of exit. Typically, however, the implementation is likely to contain more than one exit point and it may be useful for a developer to know from which specific one a function returned. It is this information, described as an offset from the start of the function, that is given by a return probe's arg0. Your D script, then, is attempting to update part of the program or library itself; although the addition of arg0 makes the destination address somewhat random, the result is most likely still within the text section, which is read-only.
Secondly, in the common case, a function's implementation returns a value by storing it in a specific register; e.g. %rax on amd64. Thus overriding a return value would neccessitate overriding a register value. This is impossible because DTrace's access to the user-land registers is read-only.
It is possible that a function is implemented in such a way that, as it returns, it recovers the return value from a specific memory location before writing it into the appropriate register. If this were the case then one could, indeed, modify the value in memory (given its location) just before it is accessed. However, this is going to work for only a subset of cases: the return value might equally be contained in another register or else simply expressed as a constant in the program text itself. In any case, it would be far more trouble than it's worth given the existence of more appropriate debugging tools.
I am trying to debugg the project on MSVS 2010.
Implementation - c++; when i am degubbing the source code, i get the following failure reported by MSVS.
Failure reported:
"First chance exception at 0x00000013fb5b9ee in unit.exe: 0xc00000005 access voilation reading location 0x00000000000000c."
the problem lies in obtaining address.
int base = (*(abc::g_runc1.m_paulsenderpin.m_lastchunk_p)).xcpp::cxcppoutput::m_baseaddress;
my project is very big to include the source code,
In short it can be described as:
- paul is a module with sender pin connected to c1.
- xcpp is the interface
this source code and the project is correct and works without failure on ARM compiler, but on MSVS it gives access violation error.
On msdn there are some posts about permission set by assembly, and which avoids to read the addressed location. if so, how to change it... ?
or is there any better option to find the problem...?
Any help is appreciated.
Your code is trying to access location that actually isn't owned by it's process. No data of user applications can be located at addresses so close to zero. As your expressions is too long to simply find where is the member containing zero reference, my tip is m_last chunk_p, and the m_baseaddress seems to be member at offset 12.
There is one simple explanation why does your code work fine when it's compiled by something that works with ARM: ARM uses aligned memory access, so class and structure members are aligned to full blocks, although they don't always use whole space allocated for them. Therefore you use bigger pointer or wrong memset parameters somewhere in your code and your pointer gets overwritten.
Problem may also disappear when you compile it with another version of (possibly another) compiler (or non machine with different processor architecture 32/64), as the size of fundamental types isn't always the same.
You should try to check what pointed is actually zero (or possibly 12) in your expression and try to set a watch on it. Be sure you use sizeof properly everywhere.
The Problem lies with the memory addressing, in ARM debugger 32 bits and MSVS10 48 bits of addressing, because of it the MSB byte is lost and so cannot find the correct memory address...!!!
I'm trying to understand a small binary using gdb but there is something I can't find a way to achieve : how can I find the list of jumps that point to a specified address?
I have a small set of instructions in the disassembled code and I want to know where it is called.
I first thought about searching the corresponding instruction in .text, but since there are many kind of jumps, and address can be relative, this can't work.
Is there a way to do that?
Alternatively, if I put a breakpoint on this address, is there a way to know the address of the previous instruction (in this case, the jump)?
If this is some subroutine being called from other places, then it must respect some ABI while it's called.
Depending on a CPU used, the return address (and therefore a place from where it was called) will be stored somewhere (on stack or in some registers). If you replace original code with the one that examines this, you can create a list of return addresses. Or simpler, as you suggested, if you use gdb and put a breakpoint at that routine, you can see from where it was called by using a bt command.
If it was actual jump (versus a "jump to subroutine") that led you there (which I doubt, if it's called from many places, unless it's a kind of longjmp/setjmp), then you will probably not be able to determine where this was called from, unless the CPU you are using allows you to trace the execution in some way.
Is it possible without any file.out and source code, but just the binary?
Is it possible, knowing the name of a var, found and read at runtime the value?
Is it possible, knowing the name of a var, found and read at runtime the value
It depends.
If the variable is a global, and the binary is not stripped, then you should be able to examine its value with a simple
x/gx &var
print var
The latter may print the variable as if it were of type int (if the binary has no debug info), which may not be what you are looking for.
If the variable is local (automatic), then you can print it only while inside the routine in which it is declared (obviously).
If the binary has debug info, then simple print var in correct context should work.
If the binary doesn't, you'll have to figure out the in-memory address of the variable (usually at fixed offset from stack pointer of frame pointer register), and examine that address. You can often figure out a lot about the given routine by disassembling it.
Update:
if I strip the binary, is harder to do the reverse engineering?
Sure: the less info you provide to the attacker, the harder you make his job.
But you also make your job harder: when your binary doesn't work, often your end-user will know more about his system than you do. Often he will load your binary into GDB, and tell you exactly where your bug is. With a stripped executable, he likely wouldn't be able to do that, so you'll guess back and forth, and after a week of trying will lose that customer.
And there is nothing you can do to prevent a sufficiently determined and sufficiently skilled hacker with root access to his system and hardware from reverse engineering your program.
In the end, in my experience, anti-circumvention techniques are usually much more trouble than they are worth.