

Flag: Tornado!
Hurricane!
|
 |
Topic created on: October 15, 2007 13:53 CDT by acidx  .
Ok, so i don't post much, i don't really even talk much, but i've been using openrce,rootkit.com and google for informationf or as long as i can remember. I truely love reverse engineering and recently have gotten back into it after being disappointed in myself for not being able to figure this one thing out.
Class/Object Reconstruction
I don't know why i just can't get it, even in dll's where the class is almost completely exported i still can't get it to work properly(ie stack gets corrupted after the deconstuctor executes).
I know there is things like OBJ_REC(which compiled but i don't feel like troubleshooting the crash that always happens when i try and use it).
Just looking for feedback in the proper direction i should take for class/object reconstruction and having them work right and be useful afterwards. Weather it be something already existing, the direction in which to create my own automater reconstructor, something?
I figure i'm just over looking the obvious in it all which i tend to do often, and am looking for the community to finally point it out to me. So i don't get frustrated and give up again.
I'm not sure what "stack gets corrupted after the deconstuctor executes" means (you're trying to reproduce the code in C++?), but you could start with my part two of my article:
https://www.openrce.org/articles/full_view/23
If you did read it then maybe you can start by explaining what you've got and what you figured out from it.
|
Ive read over it, i'll probably read over it again tonight, and double check everything once more. Before i post the code.
Error: A buffer overrun has occurred in yimagelibtest.exe which has corrupted the program's internal state.
It used to say something more about the stack before i found that i was missing an enum. when i debug it it lands here
__declspec(noinline)
void __cdecl _CRT_DEBUGGER_HOOK(int _Reserved)
{
/* assign 0 to _debugger_hook_dummy so that the function is not folded in retail */
(_Reserved);
_debugger_hook_dummy = 0;
}
thats when its compiled in debug and running in msvc, if i load it in ida, and debug it when WinMain returns, i get
The instruction at 0x0 referenced memory at 0x0. The memory could not be read (0x00000000 -> 00000000)
if i try and single step the program termination i get
The instruction at 0xFFFFFFFF referenced memory at 0xFFFFFFFF. The memory could not be read (0xFFFFFFFF)
i don't know if this provides any insight as to why? but i'll def re read your article again tonight.
|
|
this is also the CYImage class i'm trying to rebuild which is exported from YImage.dll in Yahoo Messenger.
|
acidx
and what you expected?! you said there was buffer overflow error, so, stack is corrupted and you can't return from the function, since return address was overwritten. use key /GS to force stack checking (for newer VC version only).
how to work with corrupted stack? well, forget about stack. deal with registers. for example, EBX may contain "this" pointer, points to object that was called before crash. other registers also may have interesting values showing where crash actually happens.
it's very simple to reconstruct classes if program uses RTTI or Borland VCL library (DEDE is my favorite tool to analyze DELHI and Builder programs).
BTW, I wrote about classes reconstruction here. also I'd written a set of articles how to analyze crash dumps. I'm going to upload them onto my server.
|
I wasn't worried about the stack, thats just what it was complaining about at first. I will look over both igorsk's article again, and yours. If the object was allocated, and the reconstructed object wasn't the exact size of the original(ie to small) would it cause a buffer overflow? Because the more i think about it thats what its starting to seem like. Then again i'm not to familiar with the actual allocation of exported objects in memory. For example does vc allocate the object to the size of the header definition of it? or does it get allocated based on the actual size of the exported object? If you don't understand what i'm saying then:
we have a dll that exports
class b
{
int func1();
int func2();
int b;
char *test;
}
and then we have the header definition
class a
{
int func2();
char *test;
}
the size of which one will get allocated? when we do
a test;
test.func2();
?
the size of class b? or the size of class a?
|
size of the class a.
btw,
class b
{
int func1();
int func2();
int b;
char *test;
}
doesn't works, change "int b" to "int x" for example.
and why you don't want to compile your example and disassemble it? or just tell to compiler produce .asm file? do it and see yourself.
|
you got a point there, and yeah i was just throwing an example together not exactly code i'm using so having variable of b doesn't much matter at this point. I do think after doing some more reading last night that i'm going to start with my own and work from there. Because the following may just be to much for the first class to be reversing. I just figured since the majority of it is exported, it couldn't be to terribly difficult.
class CYImage
{
public:
CYImage();
virtual ~CYImage();
CYImage(class CYImage const &);
class CYImage const & operator=(class CYImage const &);
operator struct HBITMAP__ *(void)const ;
enum FileType {BMP=1,GIF,JPG,PNG};
void ConvertToGrayscale(void);
struct HBITMAP__ * CreateAntiAliasedBitmap(struct HBRUSH__ *)const ;
void Desaturate(unsigned char);
bool Draw(struct HDC__ *)const ;
bool Draw(struct HDC__ *,struct tagPOINT const &)const ;
bool Draw(struct HDC__ *,struct tagRECT const &)const ;
bool Draw(struct HDC__ *,struct tagRECT const &,struct tagPOINT const &)const ;
bool Draw(struct HDC__ *,struct tagRECT const &,struct tagPOINT const &,unsigned char)const ;
bool Draw(struct HDC__ *,int,int)const ;
void Flip(unsigned int);
int GetHeight(void)const ;
static enum FileType __cdecl GetImageFileTypeByExtension(char const *);
int GetWidth(void)const ;
static void __cdecl InitGDIHelpers(void);
bool IsLoaded(void)const ;
bool IsOpaque(void)const ;
bool Load(char const *);
bool LoadBMP(struct HINSTANCE__ *,int);
bool LoadBMP(char const *);
bool LoadGIF(struct HINSTANCE__ *,int);
bool LoadGIF(char const *);
bool LoadHBITMAP(struct HBITMAP__ *);
bool LoadHCURSOR(struct HICON__ *,unsigned long);
bool LoadHICON(struct HICON__ *,unsigned long);
bool LoadJPG(struct HINSTANCE__ *,int);
bool LoadJPG(char const *);
bool LoadJPG(unsigned char const *,unsigned int);
bool LoadPNG(struct HINSTANCE__ *,int);
bool LoadPNG(char const *);
bool LoadPNG(unsigned char const *,unsigned int);
void MakeOpaque(unsigned long);
void MakeOpaque(struct HBRUSH__ *);
void Resize(int,int,enum ResizeOption,enum ResizeQuality);
void Rotate(int);
bool SaveJPG(char const *)const ;
bool SavePNG(char const *)const ;
void SetAlpha(void);
void SetColorKey(unsigned long);
void SetOpaque(void);
void SetTransparentIndex(int);
static void __cdecl UninitGDIHelpers(void);
void Unload(void);
static bool __stdcall YAlphaBlend(struct HDC__ *,int,int,int,int,struct HDC__ *,int,int,int,int,bool,unsigned char);
protected:
void CheckGIFTransparency(class CSourceBlock &);
static unsigned int __cdecl ComputePixelBufferSize(int,int,int);
static unsigned int __cdecl ComputeStride(int,int);
static bool __cdecl Convert16To24(struct tagDIBSECTION const &,unsigned char *,unsigned int);
bool DrawWithKey(struct HDC__ *,struct tagRECT const &,struct tagPOINT const &,struct HDC__ *)const ;
static bool __cdecl ExpandPalette(struct HBITMAP__ *,unsigned char *,unsigned int);
bool LoadBMPWithLoadImage(struct HINSTANCE__ *,char const *,unsigned int);
bool LoadFromIPicture(struct IPicture *);
bool LoadJPG(class CSourceBlock &);
bool LoadMasked(struct HBITMAP__ *,struct HBITMAP__ *,unsigned long);
bool LoadOLE(struct HINSTANCE__ *,int,char const *);
bool LoadOLE(char const *);
bool LoadPNG(class CSourceBlock &);
static void __cdecl NormalizeDIBSection(struct tagDIBSECTION *);
static int __cdecl NormalizeDegrees(int);
static unsigned long __cdecl RGB32(unsigned long);
static unsigned int __cdecl RoundUpToMultiple(unsigned int,unsigned int);
static bool __cdecl ScanForAlpha(struct HBITMAP__ *);
static bool __cdecl StripAlpha(struct tagDIBSECTION const &,unsigned char *,unsigned int);
static bool __cdecl SynthesizeAlphaFromColorKey(struct tagDIBSECTION const &,unsigned long,unsigned char *,unsigned int);
private:
static bool s_bInitialized;
static struct HINSTANCE__ *s_hmodMSImage;
static int (__stdcall*s_pfnAlphaBlend)(struct HDC__ *,int,int,int,int,struct HDC__ *,int,int,int,int,struct _BLENDFUNCTION);
};
|
|
These are only methods, you need to restore the fields too. Find a place where an instance of such class is created and check the value passed to the new() operator - that will be its size. Then go through all the methods and watch accesses to the this pointer, those will be accesses to the class' fields.
|
|
ok, i was wondering how to find it's actual size for comparison to see how much i was actually missing. I just wrote some small test classes to play with and once i get those(re reading your article again as well today didn't have time last night). I'm going to go back to this, and then hopefully i can move on to the original goal i had. Thanks and hopefully i can soon contribute back to the community.
|
Note: Registration is required to post to the forums.
|
|
 |
|
There are 31,328 total registered users.
|
|