Im trying to get the starting address of buf. So I compile the following program and load it up in gdb.
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv) {
char buf[128];
if(argc < 2) return 1;
strcpy(buf, argv[1]);
printf("%s\n", buf);
return 0;
}
On disassembling main we get:-
(gdb) disassemble main
Dump of assembler code for function main:
0x080483b4 <main+0>: push ebp
0x080483b5 <main+1>: mov ebp,esp
0x080483b7 <main+3>: sub esp,0xa8
0x080483bd <main+9>: and esp,0xfffffff0
0x080483c0 <main+12>: mov eax,0x0
0x080483c5 <main+17>: sub esp,eax
0x080483c7 <main+19>: cmp DWORD PTR [ebp+0x8],0x1
0x080483cb <main+23>: jg 0x80483d9 <main+37>
0x080483cd <main+25>: mov DWORD PTR [ebp-0x8c],0x1
0x080483d7 <main+35>: jmp 0x8048413 <main+95>
0x080483d9 <main+37>: mov eax,DWORD PTR [ebp+0xc]
0x080483dc <main+40>: add eax,0x4
0x080483df <main+43>: mov eax,DWORD PTR [eax]
0x080483e1 <main+45>: mov DWORD PTR [esp+0x4],eax
0x080483e5 <main+49>: lea eax,[ebp-0x88]
0x080483eb <main+55>: mov DWORD PTR [esp],eax
0x080483ee <main+58>: call 0x80482d4 <strcpy#plt>
0x080483f3 <main+63>: lea eax,[ebp-0x88]
0x080483f9 <main+69>: mov DWORD PTR [esp+0x4],eax
0x080483fd <main+73>: mov DWORD PTR [esp],0x8048524
0x08048404 <main+80>: call 0x80482b4 <printf#plt>
0x08048409 <main+85>: mov DWORD PTR [ebp-0x8c],0x0
0x08048413 <main+95>: mov eax,DWORD PTR [ebp-0x8c]
0x08048419 <main+101>: leave
0x0804841a <main+102>: ret
End of assembler dump.
In order to find the starting address of buf, I need to see the address which is being loaded into eax. When I set a breakpoint at 0x080483e5 or 0x080483ee I get the following.
(gdb) b 0x080483eb
Function "0x080483eb" not defined.
Make breakpoint pending on future shared library load? (y or [n])
(gdb) run test
Starting program: /levels/level05 test
test
Program exited normally.
What am I doing wrong? Why doesn't the program execution pause at that address?
If you want to set a break point at an address, you have to say b *0x080483eb
See here for more info.
You should also compile your program with -g , and without optimization. You can just break main to stop when you get to main, step a few lines with n and print buf with p buf
Related
I asked this question few days ago.
I wanted to get the stack allocation size (after the function creation). The answer suggests to do:
if((INS_Opcode(ins) == XED_ICLASS_ADD || INS_Opcode(ins) == XED_ICLASS_SUB) &&
REG(INS_OperandReg(ins, 0)) == REG_STACK_PTR && INS_OperandIsImmediate(ins, 1)
Which in theory is correct and does make sense. But, it doesn't work in practice (correct me if I'm wrong here). It works perfectly fine if I remove REG(INS_OperandReg(ins, 0)) == REG_STACK_PTR check. Why? Because pin doesn't detect the REG_STACK_PTR register when REG(INS_OperandReg(ins, 0)) is used to detect it. rather, it detects ah (which I believe is RAX), when I do check against add rsp, 0xffffffffffffff80 instruction (so, every time it gives: register: ah), as can be seen in my output below:
in
register: rbp
40051e push rbp
register: *invalid*
value: -128
40051f mov rbp, rsp
register: ah
400522 add rsp, 0xffffffffffffff80
register: *invalid*
400526 mov dword ptr [rbp-0x28], 0x7
register: *invalid*
40052d mov dword ptr [rbp-0x64], 0x9
register: eax
400534 mov eax, 0x0
register: *invalid*
400539 call 0x4004e6
register: rbp
4004e6 push rbp
register: *invalid*
value: 64
4004e7 mov rbp, rsp
register: ah
4004ea sub rsp, 0x40
register: *invalid*
4004ee mov dword ptr [rbp-0xc], 0x4
register: rax
4004f5 lea rax, ptr [rbp-0xc]
register: *invalid*
4004f9 mov qword ptr [rbp-0x8], rax
register: rax
4004fd mov rax, qword ptr [rbp-0x8]
register: eax
400501 mov eax, dword ptr [rax]
register: *invalid*
400503 mov esi, eax
register: edi
400505 mov edi, 0x4005d0
register: eax
40050a mov eax, 0x0
register: rdi
40050f call 0x4003f0
register: rdi
4003f0 jmp qword ptr [rip+0x200c22]
register: *invalid*
4003f6 push 0x0
register: *invalid*
4003fb jmp 0x4003e0
register: *invalid*
4003e0 push qword ptr [rip+0x200c22]
register: rdi
4003e6 jmp qword ptr [rip+0x200c24]
4
register: *invalid*
400514 mov dword ptr [rbp-0x3c], 0x3
40051b nop
register: *invalid*
40051c leave
register: *invalid*
40051d ret
register: eax
40053e mov eax, 0x0
register: *invalid*
400543 leave
out
Well, interestingly it does this for every occurrences of rsp (i.e. it detects ah instead of rsp). Also, it always prints the instruction 400522 add rsp, 0xffffffffffffff80, including rsp (So, why it doesn't print ah here?)
If ah represents rsp in some way, then I can always detect ah using: REG(INS_OperandReg(ins, 0)) == REG_AH. But, I want to understand what is going on here.
My code:
#include <iostream>
#include <fstream>
#include "pin.H"
#include <unordered_map>
// key to open the main Routine
static uint32_t key = 0;
// Ins object mapping
class Insr
{
private:
// Disassembled instruction
string insDis;
INS ins;
public:
Insr(string insDis, INS ins) { this->insDis = insDis; this->ins = ins;}
string get_insDis() { return insDis;}
INS get_ins() { return ins;}
};
// Stack for the Insr structure
static std::unordered_map<ADDRINT, Insr*> insstack;
// This function is called before every instruction is executed
VOID protect(uint64_t addr)
{
if (addr > 0x700000000000)
return;
if (!key)
return;
// Initialize the diassembled instruction
string insdis = insstack[addr]->get_insDis();
INS ins = insstack[addr]->get_ins();
if (INS_OperandCount(ins) > 0)
{
if (REG(INS_OperandReg(ins, 0)) == REG_AH)
std::cout << "register: " << REG_StringShort(REG(INS_OperandReg(ins, 0))) << '\n';
}
if((INS_Opcode(ins) == XED_ICLASS_ADD || INS_Opcode(ins) == XED_ICLASS_SUB) &&
INS_OperandIsImmediate(ins, 1))
{
int value = INS_OperandImmediate(ins, 1);
std::cout << "value: " << dec<<value << '\n';
}
std::cout << hex <<addr << "\t" << insdis << std::endl;
}
// Pin calls this function every time a new instruction is encountered
VOID Instruction(INS ins, VOID *v)
{
if (INS_Address(ins) > 0x700000000000)
return;
insstack.insert(std::make_pair(INS_Address(ins), new Insr(string(INS_Disassemble(ins)),
ins)));
// if (REG_valid_for_iarg_reg_value(INS_MemoryIndexReg(ins)))
// std::cout << "true" << '\n';
// Insert a call to docount before every instruction, no arguments are passed
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)protect, IARG_ADDRINT, INS_Address(ins),
IARG_END);
}
// Lock Routine
void mutex_lock()
{
key = 0;
std::cout<<"out\n";
}
void mutex_unlock()
{
key = 1;
std::cout<<"in\n";
}
void Routine(RTN rtn, VOID *V)
{
if (RTN_Name(rtn) == "main")
{
RTN_Open(rtn);
RTN_InsertCall(rtn, IPOINT_BEFORE, (AFUNPTR)mutex_unlock, IARG_END);
RTN_InsertCall(rtn, IPOINT_AFTER, (AFUNPTR)mutex_lock, IARG_END);
RTN_Close(rtn);
}
}
INT32 Usage()
{
cerr << "This tool counts the number of dynamic instructions executed" << endl;
cerr << endl << KNOB_BASE::StringKnobSummary() << endl;
return -1;
}
int main(int argc, char * argv[])
{
// Initialize the symbol table
PIN_InitSymbols();
// Initialize pin
if (PIN_Init(argc, argv)) return Usage();
PIN_SetSyntaxIntel();
// Routine instrumentation
RTN_AddInstrumentFunction(Routine, 0);
// Register Instruction to be called to instrument instructions
INS_AddInstrumentFunction(Instruction, 0);
// Start the program, never returns
PIN_StartProgram();
return 0;
}
I have few questions regarding that.
How can I understand such a behavior? And how can I detect rsp if I want to? Lastly, how does the instruction prints rsp, but REG(INS_OperandReg(ins, 0)) == REG_STACK_PTR can not detect it?
The INS objects are only valid inside instrumentation routines, such as your Instruction routine. The INS type is nothing but a 32-bit integer that identifies an instruction. The Pin runtime internally maintains a table that maps these 32-bit integers to specific static instructions. It creates such a table whenever it's about to call an instrumentation routine. When the instrumentation routine returns, there is no guarantee that any of these identifiers map to the same static instructions and they may not even be valid. So when you save a copy of an INS object in the following line of code:
insstack.insert(std::make_pair(INS_Address(ins), new Insr(string(INS_Disassemble(ins)),
ins)));
that copy is only useful in the same instance of the Instruction routine. The next time the Instruction routine is called (or any other instrumentation routine), an instruction identifier might be reused for other instructions.
If you really want to pass an instruction to an analysis routine, you have two options:
Copy the actual bytes of the instruction to a buffer and pass the address of the buffer and later decode it using the XED API.
Pass the address of the instruction and later decode it using the XED API. This works if the instruction is guaranteed to be available at the same location later.
I asked this question few days ago.
I wanted to get the stack allocation size (after the function creation). The answer suggests to do:
if((INS_Opcode(ins) == XED_ICLASS_ADD || INS_Opcode(ins) == XED_ICLASS_SUB) &&
REG(INS_OperandReg(ins, 0)) == REG_STACK_PTR && INS_OperandIsImmediate(ins, 1)
Which in theory is correct and does make sense. But, it doesn't work in practice (correct me if I'm wrong here). It works perfectly fine if I remove REG(INS_OperandReg(ins, 0)) == REG_STACK_PTR check. Why? Because pin doesn't detect the REG_STACK_PTR register when REG(INS_OperandReg(ins, 0)) is used to detect it. rather, it detects ah (which I believe is RAX), when I do check against add rsp, 0xffffffffffffff80 instruction (so, every time it gives: register: ah), as can be seen in my output below:
in
register: rbp
40051e push rbp
register: *invalid*
value: -128
40051f mov rbp, rsp
register: ah
400522 add rsp, 0xffffffffffffff80
register: *invalid*
400526 mov dword ptr [rbp-0x28], 0x7
register: *invalid*
40052d mov dword ptr [rbp-0x64], 0x9
register: eax
400534 mov eax, 0x0
register: *invalid*
400539 call 0x4004e6
register: rbp
4004e6 push rbp
register: *invalid*
value: 64
4004e7 mov rbp, rsp
register: ah
4004ea sub rsp, 0x40
register: *invalid*
4004ee mov dword ptr [rbp-0xc], 0x4
register: rax
4004f5 lea rax, ptr [rbp-0xc]
register: *invalid*
4004f9 mov qword ptr [rbp-0x8], rax
register: rax
4004fd mov rax, qword ptr [rbp-0x8]
register: eax
400501 mov eax, dword ptr [rax]
register: *invalid*
400503 mov esi, eax
register: edi
400505 mov edi, 0x4005d0
register: eax
40050a mov eax, 0x0
register: rdi
40050f call 0x4003f0
register: rdi
4003f0 jmp qword ptr [rip+0x200c22]
register: *invalid*
4003f6 push 0x0
register: *invalid*
4003fb jmp 0x4003e0
register: *invalid*
4003e0 push qword ptr [rip+0x200c22]
register: rdi
4003e6 jmp qword ptr [rip+0x200c24]
4
register: *invalid*
400514 mov dword ptr [rbp-0x3c], 0x3
40051b nop
register: *invalid*
40051c leave
register: *invalid*
40051d ret
register: eax
40053e mov eax, 0x0
register: *invalid*
400543 leave
out
Well, interestingly it does this for every occurrences of rsp (i.e. it detects ah instead of rsp). Also, it always prints the instruction 400522 add rsp, 0xffffffffffffff80, including rsp (So, why it doesn't print ah here?)
If ah represents rsp in some way, then I can always detect ah using: REG(INS_OperandReg(ins, 0)) == REG_AH. But, I want to understand what is going on here.
My code:
#include <iostream>
#include <fstream>
#include "pin.H"
#include <unordered_map>
// key to open the main Routine
static uint32_t key = 0;
// Ins object mapping
class Insr
{
private:
// Disassembled instruction
string insDis;
INS ins;
public:
Insr(string insDis, INS ins) { this->insDis = insDis; this->ins = ins;}
string get_insDis() { return insDis;}
INS get_ins() { return ins;}
};
// Stack for the Insr structure
static std::unordered_map<ADDRINT, Insr*> insstack;
// This function is called before every instruction is executed
VOID protect(uint64_t addr)
{
if (addr > 0x700000000000)
return;
if (!key)
return;
// Initialize the diassembled instruction
string insdis = insstack[addr]->get_insDis();
INS ins = insstack[addr]->get_ins();
if (INS_OperandCount(ins) > 0)
{
if (REG(INS_OperandReg(ins, 0)) == REG_AH)
std::cout << "register: " << REG_StringShort(REG(INS_OperandReg(ins, 0))) << '\n';
}
if((INS_Opcode(ins) == XED_ICLASS_ADD || INS_Opcode(ins) == XED_ICLASS_SUB) &&
INS_OperandIsImmediate(ins, 1))
{
int value = INS_OperandImmediate(ins, 1);
std::cout << "value: " << dec<<value << '\n';
}
std::cout << hex <<addr << "\t" << insdis << std::endl;
}
// Pin calls this function every time a new instruction is encountered
VOID Instruction(INS ins, VOID *v)
{
if (INS_Address(ins) > 0x700000000000)
return;
insstack.insert(std::make_pair(INS_Address(ins), new Insr(string(INS_Disassemble(ins)),
ins)));
// if (REG_valid_for_iarg_reg_value(INS_MemoryIndexReg(ins)))
// std::cout << "true" << '\n';
// Insert a call to docount before every instruction, no arguments are passed
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)protect, IARG_ADDRINT, INS_Address(ins),
IARG_END);
}
// Lock Routine
void mutex_lock()
{
key = 0;
std::cout<<"out\n";
}
void mutex_unlock()
{
key = 1;
std::cout<<"in\n";
}
void Routine(RTN rtn, VOID *V)
{
if (RTN_Name(rtn) == "main")
{
RTN_Open(rtn);
RTN_InsertCall(rtn, IPOINT_BEFORE, (AFUNPTR)mutex_unlock, IARG_END);
RTN_InsertCall(rtn, IPOINT_AFTER, (AFUNPTR)mutex_lock, IARG_END);
RTN_Close(rtn);
}
}
INT32 Usage()
{
cerr << "This tool counts the number of dynamic instructions executed" << endl;
cerr << endl << KNOB_BASE::StringKnobSummary() << endl;
return -1;
}
int main(int argc, char * argv[])
{
// Initialize the symbol table
PIN_InitSymbols();
// Initialize pin
if (PIN_Init(argc, argv)) return Usage();
PIN_SetSyntaxIntel();
// Routine instrumentation
RTN_AddInstrumentFunction(Routine, 0);
// Register Instruction to be called to instrument instructions
INS_AddInstrumentFunction(Instruction, 0);
// Start the program, never returns
PIN_StartProgram();
return 0;
}
I have few questions regarding that.
How can I understand such a behavior? And how can I detect rsp if I want to? Lastly, how does the instruction prints rsp, but REG(INS_OperandReg(ins, 0)) == REG_STACK_PTR can not detect it?
The INS objects are only valid inside instrumentation routines, such as your Instruction routine. The INS type is nothing but a 32-bit integer that identifies an instruction. The Pin runtime internally maintains a table that maps these 32-bit integers to specific static instructions. It creates such a table whenever it's about to call an instrumentation routine. When the instrumentation routine returns, there is no guarantee that any of these identifiers map to the same static instructions and they may not even be valid. So when you save a copy of an INS object in the following line of code:
insstack.insert(std::make_pair(INS_Address(ins), new Insr(string(INS_Disassemble(ins)),
ins)));
that copy is only useful in the same instance of the Instruction routine. The next time the Instruction routine is called (or any other instrumentation routine), an instruction identifier might be reused for other instructions.
If you really want to pass an instruction to an analysis routine, you have two options:
Copy the actual bytes of the instruction to a buffer and pass the address of the buffer and later decode it using the XED API.
Pass the address of the instruction and later decode it using the XED API. This works if the instruction is guaranteed to be available at the same location later.
I have a simple class with one private member that is accessible via get() and set() in a multithreaded environment (multi readers/multi writers). how do I lock a Get() as it only has a return statement?
class MyValue
{
private:
System::CriticalSection lock;
int val { 0 };
public:
int SetValue(int arg)
{
lock.Enter();
val = arg;
lock.Leave();
}
int GetValue()
{
lock.Enter();
return val;
//Where should I do lock.Leave()?
}
}
Don't lock anything. In your example, it is enough if you make your member an std::atomic integer.
You do not need anything else here. As a matter of fact, due to Intel architecture (strong memory ordering model), this std::atomic is not even likely to cause any performance issues.
I'm not a multithreading expert, but I think following should work.
int GetValue()
{
lock.Enter();
int ret = val;
lock.Leave();
return ret;
}
This is a demonstration of the synchronization object from hauron's answer -- I wanted to show that object construction and destruction overhead simply does not exist with an optomized build.
In the code below, CCsGrabber is an RAII-like class which enters a critical section (wrapped by a CCritical object) when constructed, then leaves it when destroyed:
class CCsGrabber {
class CCritical& m_Cs;
CCsGrabber();
public:
CCsGrabber(CCritical& cs);
~CCsGrabber();
};
class CCritical {
CRITICAL_SECTION cs;
public:
CCritical() {
InitializeCriticalSection(&cs);
}
~CCritical() { DeleteCriticalSection(&cs); }
void Enter() { EnterCriticalSection(&cs); }
void Leave() { LeaveCriticalSection(&cs); }
void Lock() { Enter(); }
void Unlock() { Leave(); }
};
inline CCsGrabber::CCsGrabber(CCritical& cs) : m_Cs(cs) { m_Cs.Enter(); }
inline CCsGrabber::CCsGrabber(CCritical *pcs) : m_Cs(*pcs) { m_Cs.Enter(); }
inline CCsGrabber::~CCsGrabber() { m_Cs.Leave(); }
Now, a global CCritical object is created (cs), which is used in SerialFunc(), along with a local CCsGrabber instance (csg) to take care of locking and unlocking:
CCritical cs;
DWORD last_tick = 0;
void SerialFunc() {
CCsGrabber csg(cs);
last_tick = GetTickCount();
}
int main() {
SerialFunc();
std::cout << last_tick << std::endl;
}
And below is the dissasembly of main() from an optimized 32-bit build. (I apologize for pasting in the whole thing -- I wanted to show that I wasn't hiding anything:
int main() {
00401C80 push ebp
00401C81 mov ebp,esp
00401C83 and esp,0FFFFFFF8h
00401C86 push 0FFFFFFFFh
00401C88 push 41B038h
00401C8D mov eax,dword ptr fs:[00000000h]
00401C93 push eax
00401C94 mov dword ptr fs:[0],esp
00401C9B sub esp,0Ch
00401C9E push esi
00401C9F push edi
SerialFunc();
00401CA0 push 427B78h ; pointer to CS object
00401CA5 call dword ptr ds:[41C00Ch] ; _RtlEnterCriticalSection#4:
00401CAB call dword ptr ds:[41C000h] ; _GetTickCountStub#0:
00401CB1 push 427B78h ; pointer to CS object
00401CB6 mov dword ptr ds:[00427B74h],eax ; return value => last_tick
00401CBB call dword ptr ds:[41C008h] ; _RtlLeaveCriticalSection#4:
std::cout << last_tick << std::endl;
00401CC1 push ecx
00401CC2 call std::basic_ostream<char,std::char_traits<char> >::operator<< (0401D90h)
00401CC7 mov esi,eax
00401CC9 lea eax,[esp+0Ch]
00401CCD push eax
00401CCE mov ecx,dword ptr [esi]
00401CD0 mov ecx,dword ptr [ecx+4]
00401CD3 add ecx,esi
00401CD5 call std::ios_base::getloc (0401BD0h)
00401CDA push eax
00401CDB mov dword ptr [esp+20h],0
00401CE3 call std::use_facet<std::ctype<char> > (0403E40h)
00401CE8 mov dword ptr [esp+20h],0FFFFFFFFh
00401CF0 add esp,4
00401CF3 mov ecx,dword ptr [esp+0Ch]
00401CF7 mov edi,eax
00401CF9 test ecx,ecx
00401CFB je main+8Eh (0401D0Eh)
00401CFD mov edx,dword ptr [ecx]
00401CFF call dword ptr [edx+8]
00401D02 test eax,eax
00401D04 je main+8Eh (0401D0Eh)
00401D06 mov edx,dword ptr [eax]
00401D08 mov ecx,eax
00401D0A push 1
00401D0C call dword ptr [edx]
00401D0E mov eax,dword ptr [edi]
00401D10 mov ecx,edi
00401D12 push 0Ah
00401D14 mov eax,dword ptr [eax+20h]
00401D17 call eax
00401D19 movzx eax,al
00401D1C mov ecx,esi
00401D1E push eax
00401D1F call std::basic_ostream<char,std::char_traits<char> >::put (0404220h)
00401D24 mov ecx,esi
00401D26 call std::basic_ostream<char,std::char_traits<char> >::flush (0402EB0h)
}
00401D2B mov ecx,dword ptr [esp+14h]
00401D2F xor eax,eax
00401D31 pop edi
00401D32 mov dword ptr fs:[0],ecx
00401D39 pop esi
00401D3A mov esp,ebp
00401D3C pop ebp
00401D3D ret
So we can see that SerialFunc() was inlined directly into main, after prologue at the beginning and before the cout code -- and nowhere to be found is any superflouous object creation, memory allocation or anything -- it just looks like the minimum amount of assembly code required to enter the critical section, get the tick count in a variable, and then leave the critical section.
Then I changed SerialFunc() to:
void SerialFunc() {
cs.Enter();
last_tick = GetTickCount();
cs.Leave();
}
With explicitly-placed cs.Enter() and cs.Leave(), just to compare with the RAII version. The generated code turned out to be identical:
int main() {
00401C80 push ebp
00401C81 mov ebp,esp
00401C83 and esp,0FFFFFFF8h
00401C86 push 0FFFFFFFFh
00401C88 push 41B038h
00401C8D mov eax,dword ptr fs:[00000000h]
00401C93 push eax
00401C94 mov dword ptr fs:[0],esp
00401C9B sub esp,0Ch
00401C9E push esi
00401C9F push edi
SerialFunc();
00401CA0 push 427B78h
00401CA5 call dword ptr ds:[41C00Ch]
00401CAB call dword ptr ds:[41C000h]
00401CB1 push 427B78h
00401CB6 mov dword ptr ds:[00427B74h],eax
00401CBB call dword ptr ds:[41C008h]
std::cout << last_tick << std::endl;
00401CC1 push ecx
00401CC2 call std::basic_ostream<char,std::char_traits<char> >::operator<< (0401D90h)
...
In my opinion, SergeyA's answer is best for the given situation -- a critical section for synchronizing reads and writes from/to 32-bit variables is excessive. However, if something comes up which calls for a critical section or mutex, using an RAII-like object to simplify your code is probably not going to incur significant (or even any) object creation overhead.
(I used Visual C++ 2013 to compile the code above)
Consider using a class wrapper locking in ctor, and unlocking in dtor. See standard implementation: http://en.cppreference.com/w/cpp/thread/unique_lock
This way you don't need to remember about unlocking in case of complex code or exceptions thrown within your code, altering the normal execution.
Why does this code call the wrong virtual function? It calls the one at offset 8 while it should be calling the one at offset 4. If I rename the function at 8 it correctly calls the one at 4. Code gen bug? Something silly I'm missing?
Source:
class surface_c
{
public:
virtual ~surface_c() = 0; // 0
virtual bool blit(int) = 0; // 4
virtual bool blit() = 0; // 8
};
int main()
{
surface_c* surface;
surface->blit(0);
return 0;
}
Disassembly:
int main()
{
00A11250 push ebp
00A11251 mov ebp,esp
00A11253 sub esp,44h
00A11256 push ebx
00A11257 push esi
00A11258 push edi
surface_c* surface;
surface->blit(0);
00A11259 push 0
00A1125B mov eax,dword ptr [surface]
00A1125E mov edx,dword ptr [eax]
00A11260 mov ecx,dword ptr [surface]
00A11263 mov eax,dword ptr [edx+8]
00A11266 call eax
return 0;
00A11268 xor eax,eax
}
00A1126A pop edi
00A1126B pop esi
00A1126C pop ebx
00A1126D mov esp,ebp
00A1126F pop ebp
00A11270 ret
int main()
{
surface_c* surface; // surface contains garbage, as it is uninitialzed
surface->blit(0);
return 0;
}
surface must be pointing to some non-abstract subclass of surface_c, e.g.
surface = new surface_f();
where surface_f is some non-abstract subclass of surface_c, and the inherited pure virtual functions must be overridden by concrete implementations
You are calling the method on an uninitialized pointer. It is pure luck that a method is called, and the program does not crash.
I am trying to rebuild the import table of a windows pe now i have successfully enumerated through all the modules but as soon as i use loadlibrary api the application crashes could anyone point me where i am wrong??
DWORD OEP, IAT, ImageBase, LoadLib;
char *module;
// Fetch Placeholders
__asm {
mov[OEP], 0xCCCCCCCC // Orignal Entry Point
mov[IAT], 0xCCCCCCCC // Import Table Address
mov[ImageBase], 0xCCCCCCCC // Image Base
mov[LoadLib], 0xCCCCCCCC // kernel32.LoadLibraryA
}
// Fix IAT
__asm {
_it_fixup:
mov ebx, [IAT]
mov esi, [ImageBase]
add ebx, esi // image_import_descriptor
_it_loadlibrary_loop :
mov eax, [ebx + 0x0C] // eax = image_import_descriptor.Name
test eax, eax
jz _it_fixup_end
add eax, esi // ecx = module = image_import_descriptor.Name + dwImageBase
push eax
call [LoadLib] // Here when i check with ollydbg eax has advapi32.dll and says error_insufficient_buffer
inc ebx // image_import_descriptor++
test eax, eax
jnz _it_loadlibrary_loop
_it_fixup_end :
}
// Jump back
__asm {
jmp[OEP]
}
but when i use
push eax
mov ecx, [LoadLib]
call ecx
instead of
push eax
call[LoadLib]
the debugger says ecx hold dvapi32.dll i am kinda confused please tell me what is wrong here
and yes this 0xCCCCCCCC is first replace with proper information like kernel32.LoadLibraryA and all
-------------------- EDIT -------------------
updated the codes into c/c++
DWORD OEP, IAT, ImageBase, GetProc;
DWORD dwThunk, dwHintName;
typedef HMODULE(WINAPI *_LoadLibrary)(LPCSTR lpFileName);
_LoadLibrary __LoadLibrary;
// Fetch Placeholders
__asm {
mov[OEP], 0xCCCCCCCC
mov[IAT], 0xCCCCCCCC
mov[ImageBase], 0xCCCCCCCC
mov[__LoadLibrary], 0xCCCCCCCC
mov[GetProc], 0xCCCCCCCC
}
// Fix IAT
PIMAGE_DOS_HEADER pDos;
PIMAGE_IMPORT_DESCRIPTOR pDesc;
pDos = (PIMAGE_DOS_HEADER)ImageBase;
pDesc = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)ImageBase + IAT);
char *module;
while (pDesc->Name) {
module = (char *)((DWORD)ImageBase + pDesc->Name);
__LoadLibrary(module);
pDesc++;
}
// Jump back
__asm {
jmp[OEP]
}