Get symbol at address - gdb

I'm looking for a way to get a symbol that sits in a specific address.
I know that I can use the command "Info symbol [address]". The problem is that I get the nearest symbol and not the correct one. For example, the answer I get is: a + 28 in section....
The oposite way works: print &c gives the address that I use in the "info symbol" command.
I'm using class A that holds structure B that holds variable C and I want that the "info symbol" command will return C and not A + offset.
Is there any way to do it? Maybe there is a script that does the work.

I'm looking for a way to get a symbol that sits in a specific address.
I'm using class A that holds structure B that holds variable C and I want that the "info symbol" command will return C and not A + offset.
The problem is that there is no such symbol. That is, given this code:
struct Foo { int x; };
struct Bar { int y; struct Foo xx; };
struct Bar bb;
There exists a global symbol bb, but there does not exist any symbol bb.xx in the symbol table.
So you shouldn't be asking "what symbol sits at &bb.xx, but "what field of symbol bb sits at &bb.xx". I don't believe there is an easy way for GDB to answer that.
The best you could do is maintenance print type bb, which will print (among other things):
nfields 2 0x2877c70
[0] bitpos 0 bitsize 0 type 0x2877a70 name 'y' (0x287a9ba)
type node 0x2877a70
name 'int' (0x287a9a9)
tagname '<NULL>' (0x0)
code 0x8 (TYPE_CODE_INT)
length 4
...
[1] bitpos 32 bitsize 0 type 0x2877570 name 'xx' (0x287a9c6) << this is the address you want
type node 0x2877570
name '<NULL>' (0x0)
tagname 'Foo' (0x287a98e)
code 0x3 (TYPE_CODE_STRUCT)
length 4
objfile 0x273cc10
...

Related

why does printing address of a variable print random values on every execution even if its a logical address in C?

From this question : function pointer :physical or virtual address
I understood that when I print the address of any variable , it prints the virtual address . But I had read in books that implied that for each process , the virtual address starts from 0 and the MMU will actually take care of the address translation.
So when I execute the program many times , i see some random addresses ? Why does this happen ? Why doesn't it start from 0 ? Is the address denoting some offset from the base address of the actual process ? If so , doesn't it mean that its the physical address ?
I am running my pc on POP os and my system is also new.
Here are the values when i print the address of my variable in each execution :
0x7ffc62f83904
0x7ffd78dee214
0x7fff2b69f6c4
0x7ffcc89680a4
0x7ffdc5cbf514
0x7ffd00540714
0x7ffd743ac3d4
0x7ffe7c5a9914
0x7ffd1ea1d214
0x7ffe21c30d64
0x7ffe885d9de4
0x7ffc5d8432e4
0x7ffe87ebff04
0x7ffc726e88d4
0x7ffef650e684
0x7fff0a62a2f4
0x7ffe89e3aed4
0x7ffd77e596f4
0x7ffcfcf76c54
0x7fff9a2cf654
0x7ffe3a8cbf84
0x7ffc4e127704
0x7ffce1a9f894
0x7ffd908828a4
0x7ffc88b0c6b4
0x7ffc2dd04804
0x7ffda3991c24
0x7fffad288da4
0x7ffd34da2994
0x7ffc3e3dcf54
0x7ffc6780b224
0x7ffee8f41554
0x7ffd369d9c54
0x7ffe5bdfca14
0x7ffc9a772454
0x7ffe03665d04
0x7ffce0eeb234
0x7ffc4fad04a4
0x7ffea8c715e4
0x7ffc6c3eb7f4
0x7ffea32a5e24
0x7ffea7729394
0x7ffdfbd2eab4
0x7fff36934134
0x7ffe9e15b1e4
0x7ffe12a07194
0x7ffc1b2fce34
0x7ffc3a82b684
0x7ffe56aad1d4
0x7ffd00d59c54
0x7fff58636474
0x7ffdc8940964
0x7ffed8146aa4
0x7ffd81794c94
0x7ffdce6ac874
0x7fff761a79c4
0x7ffe8fc95a24
0x7ffd3fb95464
0x7ffdbceeeb84
0x7ffc1582c2d4
0x7ffd47f0e8b4
0x7ffdd55b12f4
0x7ffc802a3db4
0x7ffebe9634a4
0x7ffec809acf4
0x7ffd0dfe0354
0x7ffc80eeb8d4
0x7fff1914b3b4
0x7fff3fee60d4
0x7ffccf1febf4
0x7ffdfe68c264
0x7ffd631c8184
0x7ffd814bc3c4
0x7ffc53a2d3d4
0x7fff49d96e14
0x7ffc16144e14
0x7ffecfe11904
0x7ffeaa3dc584
0x7ffcfb3a2894
0x7fff8a6a04b4
0x7ffcf0e035f4
0x7ffe060a7654
0x7ffce2a00954
0x7ffcc81980f4
0x7ffc0c706034
0x7fff172e4f34
0x7ffd62c963e4
0x7ffcf00501a4
0x7ffeec50b044
0x7ffd0bbb2be4
0x7ffff8fbebf4
0x7ffd6e127ac4
0x7fff0f2b9714
0x7ffe8b6da014
0x7ffc58f83344
0x7ffc3aa463e4
0x7fff8b28c9d4
0x7ffe1799f8a4
0x7fffe398f734
0x7fffb3056f74
Should it not contain duplicates ?
Now would it contain duplicates if i run the same program multiple times in parallel which would confirm that its a virtual address and not a physical address ?
No, virtual address do not need to start at zero and generally do not do so. Each operating system, program loader, and/or linker has some default memory layout. Typically nothing is mapped at address zero so that zero can act as a null pointer and cause faults if it is dereferenced. Commonly the stack is put somewhat high in memory but adjusted by a random offset to foil attacks that rely on fixed or known addresses. That is what is causing the variation you see.
Well the address should be the same each time you compile( 0x28fefc , as an example). No it should not start from 0 since the MMU does the translation.
Try again with this code, and see if it works :
#include<iostream>
using namespace std;
int main(){
int n;
cout << &n'
}
To see the value stored in an address try this, which is called dereferencing :
#include<iostream>
using namespace std;
int main(){
int n = 10;
cout << *(&n);
}
If the problem persists, i think is the new OS..

Variable i cannot be read at compile time

I have this code:
class Set(T){
private T[] values;
T get(uint i){
return ((i < values.length) ? T[i] : null);
}
...
And when I try use this class this way:
set.Set!(int) A;
compiler gives error at the return line: set.d|9|error: variable i cannot be read at compile time
Can somebody explain, what's wrong in my code? Thanks.
That is the answer: the code simply referenced the wrong variable. The reason it gave the error it did is that T[i] is trying to get an index out of a compile-time list of types... which needs i to be available at compile time too. However, since i is a regular variable, it isn't. (You can have compile time variables btw - the result of a function may be CT evaled, or the index on a foreach over a static list, or an enum value.) However, what was wanted here was a runtime index into the array... so the values is the right symbol since it is the data instead of the type.
By Adam D. Ruppe

A variable and its pointer, have different values

Look at this program:
#include <iostream>
using namespace std;
int main()
{
const int x = 0;
int *p;
p=(int*)&x;
(*p)++;
cout<<x<<endl;
cout<<*p;
}
As you see above, I declared x as a const int, and using casting, a non const pointer named p is points to it. In the middle of the body of my program, I increased the value of x by one using (*p)++ (How is it possible, while x is defined as const?)
Now,when I print *p and x, they returns different values, while *p is supposed to point to address of x :
ap1019#sharifvm:~$ ./a.out
0
1
Why?
The change of variable after constant removal causes the undefined behaviour, in some cases it will just work as if it wouldn't be const, in some it will cause the memory violation error, in some, it will turn your computer into the rabbit which will try to kill you...
A bit of background on the behaviour. Imagine you are a compiler. You encounter the variable:
const int blah = 3;
And then you encounter the following operation:
int foo = 4 + blah;
As you are smart compiler and you know that blah is constant - therefore it will not change, instead of reading the value from the blah, you can exchange the value from get the blah storage place in memory read it to simply add the 3 to 4 and assign it to foo.
Infant you will probably assign 7 straight away because doing the addition is pointless each time you run the program.
Lets now get into the casting away the const part.
Some really sneaky programmer is doing the following:
int * blah_pointer = (int *) & blah;
Then he is increasing the blah value by doing this operation:
(*blah_pointer)++;
What will happen - if the variable is not in the protected memory (not read only) the program will just increase the value of variable stored in memory.
Now when you will read the value which is stored in the pointer you will get the increased value!
Ok but why is there an old, unchanged value if you are reading just the blah I hear you ask:
std::cout << blah;
It is there, because the compiler try to be smart and instead of actually reading the value from blah it will just exchange it to a constant value to blah, so instead of reading it it will actually exchange it to std::cout << 3.
The undefined part is changing the constant value - you can't ever know whether the value will be stored in protected or unprotected region therefore you can't tell what will happen.
If you want the compiler to actually check the value each time it encounters it just change the definition from:
const int blah = 3;
to
const volatile int blah = 3;
It will tell the compiler the following, even though the program I am writing is not allowed to change the blah value, it may be changed during the execution of the program, therefore do not try to optimise the access to the memory and read it every time the value is used.
I hope this makes it clearer.
I think, in compilation step, your compiler will replace all your constant variables with its values (it's like #define), it's the way GNU GCC compiler optimize the code.
I'm not 100% sure about it, but i've got the same issue while learning C/C++ syntax, and it's the conclusion that i've made after disassebling (converting the binary executable to assembler code) my program.
Anyways, just try to disassemble your output and see what is really happening.

Dereferencing a pointer to a variable with an unknown type

I didn't know exactly how to explain the problem that I am having right now, so sorry if I am being vague in the title of the question.
What I am having right now is a list of virtual addresses that are being stored in variables. For example, I'm having
0x8c334dd
stored in a char variable. This address is the address of another variable that has data on it. What I want to do is to go to that address and get the data that is stored on it.
My assumption was that dereferencing the pointer would have been the best way to go, unfortunately I don't know the type of the variable that the address is pointing to, so how does dereferencing works in this case? I cannot do: *(char *) 8c334dd because I don't know the type of the variable that the address is pointing to...
If I cast it as an (int *) I get some of the data of some of the variables that some addresses are pointing to (remember that I have several addresses) but for others I am just getting an address, and I need the data (this variables are structs, chars, etc).
I am working with the ELF Symbol Table
In general, C++ or C have no way of knowing what type of pointer you have.
The usual way to solve this problem is to make the pointer point to a struct, and have a known position in the struct indicate the type of the data. Usually the known position is the first position in the struct.
Example:
// signature value; use any value unlikely to happen by chance
#define VAR_SIG 0x11223344
typedef enum
{
vartypeInvalid = 0,
vartypeInt,
vartypeFloat,
vartypeDouble,
vartypeString,
vartypeMax // not a valid vartype
} VARTYPE;
typedef struct
{
VARTYPE type;
#ifdef DEBUG
uint32_t sig;
#endif // DEBUG
union data
{
int i;
float f;
double d;
char *s;
};
} VAR;
You can then do a sanity check: you can see if the type field has a value greater than vartypeInvalid and less than vartypeMax (and you will never need to edit those names in the sanity check code; if you add more types, you add them before vartypeMax in the list). Also, for a DEBUG build, you can check that the signature field sig contains some specific signature value. (This means that your init code to init a VAR instance needs to always set the sig field, of course.)
If you do something like this, then how do you initialize it? Runtime code will always work:
VAR v;
#ifdef DEBUG
v.sig = VAR_SIG;
#endif // DEBUG
v.type = vartypeFloat;
v.data = 3.14f;
What if you want to initialize it at compile time? It's easy if you want to initialize it with an integer value, because the int type is the first type in the union:
VAR v =
{
vartypeInt,
#ifdef DEBUG
VAR_SIG,
#endif // DEBUG
1234
};
If you are using a C99 compliant version of C, you can actually initialize the struct with a field name and have it assign any type. But Microsoft C isn't C99 compliant, so the above is a nightmare if you want to init your struct with a float or double value. (If you cast the float value to an integer, C won't just change the type, it will round the value; and there is no trick I know of to portably get a 32-bit integer value that correctly represents a 32-bit float at compile time in a C program.)
Compile time float packing/punning
If you are working with pointers, though, that's easy. Just make the first field name in the union be a pointer type, cast the pointer to void * and init the struct as above (the pointer would go where 1234 went above).
If you are reading tables written by someone else's code, and you don't have a way to add a type identifier field, I don't have a general answer for you. I guess you could try reading the pointer out as different types, and see which one(s) work?
Just wanted to add something, for people out there working with the ELF symbol table, I've found the DIEs in the DWARF file easier to work with. You can get the addresses, types and names of variables using DWARF instead of ELF, and libdwarf has good documentation.

C++ , Cheat Engine / OllyDBG finding base "static" address from multi-level pointers

I'm back again, frustrated and desperately searching for help :D.
I am trying to create a cheat for a simple program, it's basically going to be a .dll file which will change an integer's value from the main program when it's injected to it using its base address. The thing is, I can't find it using cheat engine mainly because there are multiple level pointers with NEGATIVE? offsets. for example:
//Starting pointer address
0x0033FCF0 -> 200
//Finding second level pointer using "Find out what's accessing this address" in Cheat Engine
**(mov eax,[ebp+08])** // **EAX=0x00000007** , **EPB=0x0033FCE8 => mov 00000007,[0033FCE8+08]**
2nd Level Pointer:
**(0033FCE8+18) -> 200**
So I proceed to find the next pointer using "Find out what's .... " but while using T-SEARCH with the second-level pointers address and i get like 7 - 8 new static addresses.
The thing is, I cannot tell which one is correct because cheat engine REFUSES to let me add a pointer using a NEGATIVE? offset.
Example:
Base Pointer:
**mov eax,[epb-18] !!!** // Notice the **MINUS**
And on top of everything Cheat Engine refuses to accept a pointer with a negative offset!
So , is there another way of finding the base address from multiple level pointers?
OlyDBG / Idapro solutions are welcome. Thanks alot guys!
Here's the source code of the simple program I'm trying to hack:
#include <iostream>
#include <conio.h>
#include <windows.h>
#include <stdlib.h>
int main(){
int hp = 100;
while(1){
std::cout << hp << std::endl;
Sleep(3000);
hp += 10;
system("cls");
}
return 0;
}
What i am trying to do is edit the hp integer with this .dll
#include <windows.h>
#define BASE 0xBASE_POINTERS_ADDRESS_WHICH_I_NEED_TO_FIND
#define OFFSET 0xTHE_OFFSET
#define VALUE 90
void MainFunction()
{
while(1)
{
if (GetAsyncKeyState(VK_MENU)&0x8000 && GetAsyncKeyState('C')&0x8000)
MessageBox(0,L"Alt + C was pressed!",L"MessageBox! ",0);
*(int*)((*(int*)BASE) + OFFSET) = VALUE;
Sleep(100); //Let the program rest, otherwise it hogs cpu resources.
}
}
BOOL WINAPI DllMain(HINSTANCE MyInstance,DWORD reason_for_call,LPVOID PointerToVoid)
{
if (reason_for_call == DLL_PROCESS_ATTACH) CreateThread(0,0,(LPTHREAD_START_ROUTINE)&MainFunction,0,0,0);
return true;
}
By the way i am trying to hack the hp! ~ Oh , wait , i already said that , oh well , whatever ;)
Thank you guys, god bless you all!
I think you are misunderstanding the goal of Cheat Engine.
CE allows you to modify values that are stored in a durable way in memory. For example, on the heap, or in the program's static data.
For example, C++ objects are allocated in a deterministic way, and hence, they never move. This is why they can be referenced by a pointer that remains constant all over the object's lifetime. This object is sometime owned by another. If you find a pointer to the owner object, you found what is called a base pointer.
For example :
class Object
{
bool dummy;
int someField;
Object* child;
};
Now imagine you have a nested tree of 3 Object. Meaning that you have a root Object (n°1), whose child is another Object (n°2), whose child is another Object (n°3). Imagine you do something like this :
int main(int argc, char** argv)
{
Object root; // n°1
root.child = new Object(); // n°2
root.child->child = new Object(); // n°3
return 0;
}
You're interested in messing with n°3's someField value. You know that the address of someField, relative to an Object, is of +sizeof(bool) = 1.
So (void*)&(object n°3) + 1 is a pointer to the someField you want.
Now, how do you find a pointer to object n°3 ?
Knowing that the relative address of child is +sizeof(bool)+sizeof(int) = 5. We know that a pointer to object n°3 is (void*)&(object n°2) + 5.
Same goes for the address of object n°2, I'll leave that as an exercise.
But what about object n°1 ? It's not allocated on the heap. It's on the stack. Crap. So we must find another way to find the address where object n°1 is stored.
Local variables are stored on the stack. In assembly, they are identified by their offset relative to the register EBP (or ESP if the function does not change the stack).
EBP is the top of the stack, while ESP is the bottom of the stack.
In this example :
function foo()
{
int a;
double b;
}
When foo is called, the stack will be increased just enough to hold a and b, that is, sizeof(int) + sizeof(double), or 12 bytes. a will be stored at EBP - sizeof(int) = EBP - 4 (same as ESP + 8) and b will be stored at EBP - sizeof(int) - sizeof(double) = EBP - 12 (same as ESP). Attention! The compiler can change this order, so the declaration order of your variables isn't necessarily the same in memory. Optimizations can also change this completely. But let's keep this simple okay ?
So back to our main example. What local variables do we have ? root only. Therefore root will be located at EBP - 9 directly. But this, ONLY when main is the function on top of the call stack. Without a debugger, you can't do it.
Let's assume that our EBP is 0028FF28 when main is called (taken from a freshly compiled C program).
root is then at (0x0028FF28 - 9) = 0x0028FF1F;
the pointer to root.child is at (0x0028FF1F + 5) = (0x0028FF24);
Therefore, root.child is located at *0x0028FF24.
The pointer to root.child->child is at (*0x0028FF24 + 5) = (let's say 10000)
Then root.child->child is at *10000.
Finally, root.child->child.someField is at *10000 + 3.
To sum up: you just need to find the static address of root to find the rest.
root is NOT on the heap or any kind of durable memory, but it is on main's stack, which lasts during almost all the program, so it's almost as if it were permanent.
CE helps you find a static address by scanning the entire process memory space
With all this in mind, you should be able to calculate hp's relative address on the stack and find a static pointer to it (main is very, very, very likely to have a static frame address every time you launch the program). If you need help, use a debugger ! I recommend Immunity Debugger.