I am trying to learn debugging using gdb. I have got the starting.
I just want to know is it possible to list all the functions of a class including the default one provided by the compiler?
Or even other way without using and IDE
Thanks
=============================================================================
The code I am trying:
#include <iostream>
class MyClass
{
public:
void Hello() {
}
int a;
};
int main(int argc, char **argv)
{
MyClass a;
MyClass b = a;
MyClass c;
c = a;
return 0;
}
=UPDATE 3====================================================================
I also want to list the compiler provided function name, if possible in gdb.
My question is in addition to question posted at
How to list class methods in gdb?
You have written too simple class. This advice:
Once you have the executable loaded in gdb, type break (or b) and hit the tab key.
is correct in general but in your case MinGW does not create anything for MyClass. I compiled your program with MinGW and disassembled it:
(gdb) disassemble /m main
Dump of assembler code for function main(int, char**):
13 {
0x0040138c <+0>: push %ebp
0x0040138d <+1>: mov %esp,%ebp
0x0040138f <+3>: and $0xfffffff0,%esp
0x00401392 <+6>: sub $0x10,%esp
0x00401395 <+9>: call 0x40193c <__main>
14 MyClass a;
15 MyClass b = a;
0x0040139a <+14>: mov 0xc(%esp),%eax
0x0040139e <+18>: mov %eax,0x8(%esp)
16 MyClass c;
17 c = a;
0x004013a2 <+22>: mov 0xc(%esp),%eax
0x004013a6 <+26>: mov %eax,0x4(%esp)
18 return 0;
0x004013aa <+30>: mov $0x0,%eax
19 }
0x004013af <+35>: leave
0x004013b0 <+36>: ret
End of assembler dump.
As you can see only move instructions. For example your assigments c = a; results in just two move instructions and no function calls:
0x004013a2 <+22>: mov 0xc(%esp),%eax
0x004013a6 <+26>: mov %eax,0x4(%esp)
As you can see the compiler chose not to generate anything for your class. In my opinion you chose too simple example to learn that you want.
I made you example a little bit more complex
#include <iostream>
class MyClass
{
public:
void Hello()
{
std::cout << "Hello\n";
}
int a;
};
int main(int argc, char **argv)
{
MyClass a;
a.Hello();
MyClass b = a;
MyClass c;
c = a;
return 0;
}
and under gdb break My shows this:
(gdb) b MyClass
MyClass MyClass::Hello()
(gdb) b MyClass
and this is the output of nm:
D:\src-c++\test.names>nm -C ./m.exe | grep MyClass
00404060 r .eh_frame$_ZN7MyClass5HelloEv
00401c20 t .text$_ZN7MyClass5HelloEv
00401c20 T MyClass::Hello()
I just wanted to see what are the default function generated by the class, if one does not write it
Change you member class variable from 'int a' to std::string a and you will see default functions generated by compiler
#include <iostream>
#include <string>
class MyClass
{
public:
void Hello() {
}
std::string a;
};
int main(int argc, char **argv)
{
MyClass a;
MyClass b = a;
MyClass c;
c = a;
return 0;
}
And these are the compile-generated functions:
>nm -C ./a.out | grep My
00000000004009b8 W MyClass::MyClass(MyClass const&)
0000000000400964 W MyClass::MyClass()
000000000040097c W MyClass::~MyClass()
0000000000400994 W MyClass::operator=(MyClass const&)
For example, when using break, type "break" space a single quote (') the name of your class, and hit TAB.
It'll list the candidates, including generated code.
I.e. break 'PotatoLaucher::<tab>
Once you have the executable loaded in gdb, type break (or b) and hit the tab key. This will give you a list of symbols that gdb can set a breakpoint at. Often times gdb will ask you if you really want to display all the possibilities (sometimes there are thousands of possibilities).
If you have some idea of what the function might be called, type the first few characters of the function name and hit tab. This will reduce the number of results to a manageable size.
Related
My question is very specific, i want force compiler to take the code of a funtion and copy it inside a another one, like inline or __forceinline keywords can do, but i want pass the function i want to copy in the other funtion, as an argument. Here is a simple example.
using pFunc = void(*)();
void func_1() { /*some code*/ }
void func_2(pFunc function) { /*some code*/ } //after compile i want this funtion takes no argument and copy the func_1 inside this.
int main()
{
func_2(func_1);
}
so with this example the compiler will pass the pointer of func_1 as argunent to func_2, as expected.
I tried add inline keyword for func_1 and also tried to pass the argument of func_2 as reference, but compiler didn't copied the func_1 inside func_2.
Any idea how can i do that?
I use the compiler of visual studio(msvc) with toolset 2017(v141).
My project platform is x64.
You can use a noinline template function to get the asm you want
So you want the compiler to do constant-propagation into a clone of void func_2(pFunc f){ f(); }? Like what GCC might do with __attribute__((noinline)) but not noclone?
For example,
using pFunc = void(*)();
int sink, sink2;
#ifdef _MSC_VER
#define NOINLINE _declspec(noinline)
#else
#define NOINLINE __attribute__((noinline)) // noclone and/or noipa
#endif
__attribute__((always_inline)) // without this, gcc chooses to clone .constprop.0 with just a jmp func_2
void func_1() { sink = 1; sink2 = 2; }
NOINLINE static void func_2(pFunc function) { function(); }
int main()
{
func_2(func_1);
}
produces, with GCC11.3 -O2 or higher, or -O1 -fipa-cp, on Godbolt. (Clang is similar):
# GCC11 -O3 with C++ name demangling
func_1():
mov DWORD PTR sink[rip], 1
mov DWORD PTR sink2[rip], 2
ret
func_2(void (*)()) [clone .constprop.0]:
mov DWORD PTR sink[rip], 1
mov DWORD PTR sink2[rip], 2
ret
main:
# note no arg passed, calling a special version of the function
# specialized for function = func_1
call func_2(void (*)()) [clone .constprop.0]
xor eax, eax
ret
Of course if we hadn't disabled inlining of func_2, main would just call func_1. Or inline that body of func_1 into main and not do any calls.
MSVC might not be willing to do that "optimization", instead preferring to just inline func_2 into main as call func_1.
If you want to force it to make clunky asm that duplicates func_1 unnecessarily, you could use a template to do the same thing as constprop, taking the function pointer as a template arg, so you can instantiate func_2<func1> as a stand-alone non-inline function if you really want. (Perhaps with _declspec(noinline)).
Your func_2 can accept func_1 as an unused argument if you want.
using pFunc = void(*)();
int sink, sink2;
#ifdef _MSC_VER
#define NOINLINE _declspec(noinline)
#define ALWAYS_INLINE /* */
#else
#define NOINLINE __attribute__((noinline)) // not noclone or noipa, we *want* those to happen
#define ALWAYS_INLINE __attribute__((always_inline))
#endif
//ALWAYS_INLINE // Seems not needed for this case, with the template version
void func_1() { sink = 1; sink2 = 2; }
template <pFunc f>
NOINLINE void func_2() { f(); }
int main()
{
func_2<func_1>();
}
Compiles as desired with MSVC -O2 (Godbolt), and GCC/clang
int sink DD 01H DUP (?) ; sink
int sink2 DD 01H DUP (?) ; sink2
void func_2<&void func_1(void)>(void) PROC ; func_2<&func_1>, COMDAT
mov DWORD PTR int sink, 1 ; sink
mov DWORD PTR int sink2, 2 ; sink2
ret 0
void func_2<&void func_1(void)>(void) ENDP ; func_2<&func_1>
void func_1(void) PROC ; func_1, COMDAT
mov DWORD PTR int sink, 1 ; sink
mov DWORD PTR int sink2, 2 ; sink2
ret 0
void func_1(void) ENDP ; func_1
main PROC ; COMDAT
$LN4:
sub rsp, 40 ; 00000028H
call void func_2<&void func_1(void)>(void) ; func_2<&func_1>
xor eax, eax
add rsp, 40 ; 00000028H
ret 0
main ENDP
Note the duplicated bodies of func_1 and func_2.
You should check (with a disassembler) that the linker doesn't do identical code folding and just attach the both symbol names to one block of machine code.
I don't think this looks like much of an obfuscation technique; IDK why having a 2nd copy of a function with identical machine code would be a problem to reverse engineer. I guess it would maybe create more overall work, and people wouldn't notice that two calls to different functions are actually doing the same thing.
I mostly answered as an exercise in making a compiler spit out the asm I wanted it to, whether or not that has value to anyone else.
Obviously it only works for compile-time-constant function pointers; commenters have been discussing self-modifying code and scripting languages. If you wanted this for non-const function pointer args to func_1, you're completely out of luck in a language like C++ that's designed for strictly ahead-of-time compilation.
I am practicing reverse engineering software. I am using Microsoft Visual Studio. I created an empty project and then created an empty file which I called main.cpp. I then wrote the following code, compiled
int main()
{
char* str = "hello matthew";
int x = 15;
return 0;
}
When I brought the release version of the executable over to BinText and IdaPro, the string "hello matthew" was no where to be found. I could also never find the value 15 either in base 10 or hexadecimal.
I cannot begin to understand reverse engineering if I cannot find the references to the values I am looking for in the executable.
My theory is that because my program does absolutely nothing that the compiler just omitted it all, but I do not know for sure. Does anyone know why I cannot locate that string or the value 15 in the executable when I disassemble it?
I cannot begin to understand reverse engineering ...
The first step is to actually understand how the program is built out.
Before you can understand how to reverse a program, you need to understand how it's compiled and built; reversing a binary built for Windows is vastly different from reversing a binary for a *nix system.
To that, since you're using Visual Studio, you can see this answer (option 2) explaining how to enable the assembly output of your code. Alternatively if you're compiling via command line, you can pass /FAs and /Fa to generate the assembly inlined with the source.
Your code produces the following assembly:
; Listing generated by Microsoft (R) Optimizing Compiler Version 18.00.40629.0
TITLE C:\Code\test\test.cpp
.686P
.XMM
include listing.inc
.model flat
INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES
CONST SEGMENT
$SG2548 DB 'hello matthew', 00H
CONST ENDS
PUBLIC _main
; Function compile flags: /Odtp
; File c:\code\test\test.cpp
_TEXT SEGMENT
_x$ = -8 ; size = 4
_str$ = -4 ; size = 4
_main PROC
; 2 : {
push ebp
mov ebp, esp
sub esp, 8
; 3 : char* str = "hello matthew";
mov DWORD PTR _str$[ebp], OFFSET $SG2548
; 4 :
; 5 : int x = 15;
mov DWORD PTR _x$[ebp], 15 ; 0000000fH
; 6 :
; 7 : return 0;
xor eax, eax
; 8 : }
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END
While this is helpful to understand how and what your code is doing, one of the best way to start reversing, is to throw a binary in a debugger, like attaching Visual Studio to an executable, and viewing the assembly as the program is running.
It can depend on what your after since a binary could potentially be obfuscated; that is to say that there could be strings within the binary, but they could be encrypted or just scrambled so as to be unreadable until decrypted/unscrambled by some function within the binary.
So just searching for strings won't necessarily give you anything, and trying to search for a specific binary value in the assembled code is like trying to find a needle in a stack of needles. Know why your trying to reverse a program, then attack that vector.
Does anyone know why I cannot locate that string or the value 15 in the executable when I disassemble it?
As has been mentioned, and as you have guessed, the "release" binary you're searching through was optimized, and the compiler just removed the unused variables so the assembly was essentially returning 0.
I hope that can help.
the main reason is that your code does nothing useful with x and str, so they are entirely redundant!!, and no need for them to even exist in your code! so the compiler automatically removes them from the compiled code "optimization"!!.
if you really want to see them in the compiled code under debuggers, you need to use them or simply tell the compiler not to optimize this part of the code!!
This is how to tell the compiler not to optimize these variable's locations by using volatile qualifier
#include <iostream>
int main(int argc, char** argv) {
const char* volatile str = "hello matthew";
volatile int x = 15;
return 0;
}
this shows that your variables are included in the compiled code in IDA Pro
or as I also said just use them!!!
#include <iostream>
int main(int argc, char** argv) {
const char* str = "hello matthew";
int x = 15;
std::cout << str << x;
return 0;
}
I am trying to run a function on a separately allocated stack.
I want to keep the stack for later so I can restore it and resume the function.
The following code compiles and runs, but nothing prints to the screen.
#include <cstdlib>
#include <csetjmp>
#include <iostream>
using namespace std;
unsigned char stack[65535];
unsigned char *base_ptr = stack + 65535 - 1;
unsigned char *old_stack;
unsigned char *old_base;
void function()
{
cout << "hello world" << endl;
}
int main()
{
__asm
{
mov old_base, ebp
mov old_stack, esp
mov ebp, base_ptr
mov esp, base_ptr
call function
mov ebp, old_base
mov esp, old_stack
}
}
using vs2012/win8/intel Q9650
Welcome to C++ and name mangling. Function names in C++ are mangled by the compiler (such that using gcc function becomes _Z8functionv for me). This is to facilitate function overloading. The compiler keeps track of the actual names that it has given the different functions in the background so you aren't aware of it. This is a problem for any other language that tries to interact with C++.
This code won't link on my computer.
The solutions:
1) compile with g++ and pass the -S flag (so g++ -S test.cpp). And then take a look at the assembly output (cat test.s) to see what the function is called. Then change the name in "call function" to be "call _Z8functionv" (for me - it could easily be different for you).
2) use C: change the cout << to a printf statement and the above should work.
I take it that you aren't using gcc though (as the assembler is back to front for gas - I had to switch all the operands on the assembler around).
Actually I don't see any problem with your code.
Your sample taken as-is compiles, links and runs as expected.
Perhaps your problem with console settings, or some global STL/CRT initialization or whatever. Anyway, you may put a breakpoint inside your function to ensure you're getting there.
According to Intel's x86 documentation for MOV, page 3-403, you should load the SS register immediately before loading a new ESP value. That blocks any interrupts from running until ESP has been assigned.
I have 2 methods in C++ class as follows:
class myClass {
public:
void operator()( string myString ) {
// Some code
}
void myMethod() { ... }
}
For a regular method, I can simply set the breakpoint in GDB as:
b myClass::myMethod
But how do I set the breakpoint for the first method?
UPDATE:
The suggestions from initial answers (b myClass ::operator()) does not work :(
b myClass::operator()
Function "myClass::operator()" not defined.
Thanks!
gdb will also take breakpoints at specific line numbers. For example
b file.cc:45
Just the same. myClass::operator()(string) is a regular method.
If you have several overloaded operator() methods (e.g. a const and a non-const version) gdb should offer the choice where to set the breakpoint:
http://sunsite.ualberta.ca/Documentation/Gnu/gdb-5.0/html_node/gdb_35.html#SEC35
You may have to make sure that method operator()(string) is actually compiled.
Edit:
I've tested the following file test.cpp:
#include <string>
#include <iostream>
class myClass {
public:
void operator()( int i ) {
std::cout << "operator()";
}
void myMethod() {
std::cout << "myMethod";
}
};
int main() {
myClass c;
c(1);
c.myMethod();
return 0;
}
Compiled with g++ test.cpp -o test, ran gdb test (version GNU gdb 6.3.50-20050815 (Apple version gdb-1344)), typed start and only then could I set breakpoints.
b 'myClass::operator()(string)' and
b myClass::operator()
both worked.
Some C++ functions names can be really hard to type out correctly. Worse yet, gdb's autocompletion often gets confused with c++ names. I use this trick
gdb> break 'myClass::operator()<TAB>
Note the single quote at the beginning of the function. That helps gdb's autocompleter.
b myClass::operator()
I am getting the following error when trying to add a static variable to my struct:
Undefined Symbole s2::aa in module
file_name.cpp
s2 is the name of the structure and aa is the static variable.
The compiler I am using is Turbo C++ 3.0.
How do I fix this error?
I think you've probably forgotten to define the storage for the static variable:
int C::v = 0;
Static variable isn't allowed in structs in C because C requires the whole stucture elements to be placed together. To get an element value from a structure you count by the offset of the element from the beginning address of the structure.
However as far as I know you can have a static member in a C++ structure. Are you getting a specific error (which compiler?)
Why do you say this? Under g++ 4.1.2, this compiles:
#include <iostream>
struct Test
{
static int test; // declare (usually in header file)
};
int Test::test = 8; // define (usually in source file)
int
main()
{
std::cout << Test::test << std::endl;
return 0;
}
Static variables are allowed in C++ structs (as you say, they are just classes with a different default access specifier).
Static variables are not allowed in C structs, however.
This works...
typedef struct _X
{
static int x; // declare (usually in header file)
} X;
int X::x = 1; // define (usually in source file)
void _tmain(int argc, _TCHAR* argv[])
{
printf("%d", X::x);
}
effectively, you'll get a public symbol with the name [?test#Test##2HA] placed in a separate (globally accessible) segment/section in memory...
struct Test
{
static int test; // declare (usually in header file)
};
int Test::test = 8; // define (usually in source file)
int main()
{
int x = Test::test++;
return 0;
}
will translate in assembly to:
; Listing generated by Microsoft (R) Optimizing Compiler Version 19.16.27027.1
TITLE C:\WORK\C\Cpp\test.cpp
.686P
.XMM
include listing.inc
.model flat
INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES
PUBLIC ?test#Test##2HA ; Test::test
_DATA SEGMENT
?test#Test##2HA DD 08H ; Test::test
_DATA ENDS
PUBLIC _main
; Function compile flags: /Odtp
_TEXT SEGMENT
_x$ = -4 ; size = 4
_main PROC
; File c:\work\c\cpp\test.cpp
; Line 9
push ebp
mov ebp, esp
push ecx
; Line 10
mov eax, DWORD PTR ?test#Test##2HA ; Test::test
mov DWORD PTR _x$[ebp], eax
mov ecx, DWORD PTR ?test#Test##2HA ; Test::test
add ecx, 1
mov DWORD PTR ?test#Test##2HA, ecx ; Test::test
; Line 11
xor eax, eax
; Line 12
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END
Compile with:
cl /c test.cpp /TP /Fatest.asm /link /NODEFAULTLIB /entry:main
In C++ structure,you can use static variables same as class.
But you can't use static variables in C stuctures.
Because in c, we can't access static variable with stucture name. In c++ we can access static member variable with class name,like below.
ClassName::staticVariableName
'C' stucture don't provide such facility but c++ stucture does.