Click here to Skip to main content
15,169,285 members

Comments by Ghosuwa Wogomon (Top 10 by date)

Ghosuwa Wogomon 26-Nov-13 12:05pm View
Typedefs work no differently in C++ than they do in C. The typedef isn't the problem. Like I said in the post, GCC is saying there are 3

Keyword: 3
Again: 3
For Extra Measure: 3
Not: 2
There are: 3

Definitions of Engine_Module. I posted all of my code here and I know the first two are the typedef and the Engine_Module struct, but nowhere does my code define a third instance of Engine_Module. It's safe to assume g++ is using the name Engine_Module for the Engine::Module class. I was simply asking if there was a way to get around the ambiguity without changing the name.

Answering my own question though, I found out there isn't. C++ users will just have to use the class Engine::Module.
Ghosuwa Wogomon 23-Nov-13 15:28pm View
I would like to know why I as the person who asked this question cannot respond to or decline the solution of the person who posted the solution to my problem. Their answer is 100% incorrect and the user obviously has no experience with C.

typedef's are required for structs in C. A typedef with the same name as a type will not cause errors in C or C++, I have used them for years and they were designed specifically for that purpose until C++ made the struct and enum keywords optional for declarations. The this keyword is only reserved for functions that use the thiscall calling convention which is in fact nothing more than passing a hidden argument called 'this' on the stack that points to the class. Replicating C++ class functionality was the entire idea.
Ghosuwa Wogomon 23-Nov-13 15:04pm View
Like I said, I defined 2 definitions; a typedef and a struct. GCC is saying there's <3>. And no, it's not nonsense. It's the standard way of defining a new struct type that isn't anonymous. In C, a definition like:

struct MyType

has to be declared

struct MyType mt;

In C++, they remove this requirement so you can just type

MyType mt;

But for C you have to declare a type definition that overrides it. I prefer to declare structures this way because they're easier to document, I like GNU style block indentation, and I can do things you can't do with an anonymous definition like:

struct MyType
struct MyType *parent;
Ghosuwa Wogomon 23-Nov-13 14:59pm View
I probably mistyped it when I was writing the brief version for the question, but it's actually

typedef struct Engine_Module Engine_Module;
Ghosuwa Wogomon 20-Nov-13 12:30pm View
Why do you assume I haven't? There is only 1 definition of the Engine_Module struct and it's typedef in my code. When compiled as C code there are no problems whatsoever. When compiled as C++ code, there an additional definition. The only thing defined in the C++ code is the Engine namespace and the Module class.

Since using "struct Engine_Module" specifically does not solve the issue, then both definitions are structs, which means GCC is creating a second Engine_Module struct under the table without my code.
Ghosuwa Wogomon 20-Nov-13 12:16pm View
I didn't say that the the Engine::Module class derived from Engine_Module, I was saying that GCC seems to be creating a second Engine_Module struct definition for the Engine::Module class that throws an ambiguity error if I try to use struct Engine_Module in C++ code. If you try to initialize the application module with the C code and compile with g++, it states there are 3 instances called

typedef Engine_Module

Creating an instance like "struct Engine_Module module;" should fix the problem, but it doesn't. So I can only assume that both definitions are structs.
Ghosuwa Wogomon 25-Oct-13 0:00am View
Well .NET and Java is a different story, that's a JIT compiled language. Anyway, agree to disagree :P

lol, "young jedi". I may be young but I do have a lot of experience. Not from a professional background though, so you got me there :X

Actually been feeling really burned out lately. I'm at the point now where I just feel like sharing the secrets I've learned and stepping out of it to pursue a different career...
Ghosuwa Wogomon 24-Oct-13 20:59pm View
My point is that the code itself will not compile or execute properly directly after decompilation, and these are just simple functions that only call a single subroutine and return. If it can't decompile 3 lines of code without producing an error, then you shouldn't rely on it at all.

Eg. I wrote a game engine in C where the user can enumerate graphics modes, then initialize them.

struct GraphicsMode
Bool windowed, sizable, cursor;
Byte fps;
Byte colorBpp, depthBpp;
Byte stencilBpp, accumBpp;
Size screen;
Rect resolution;

GraphicsError Graphics_Initialize(struct GraphicsMode *mode);

If I were to pass my library through that decompiler and it output:

int Graphics_Initialize(BOOL *a);

This would be a serious issue. Firstly, the programmer who has to fix compiler's obvious problems would have no way of knowing BOOL is supposed to be GraphicsMode or the format of that structure, possibly assuming since it's BOOL it might mean fullscreen.
And since the Graphics_Initialize function fills out the bpp of the color, depth, stencil, and accumulation buffers, if they were to misakenly pass a boolean to the function, it'd throw a memory exception error.
Or if they were hooking the api (eg. to add an on-screen console), they wouldn't fill out the structure properly and give the game garbage for the screen and resolution sizes.

It's a big issue, and why you should never trust decompiled code. It's inaccurate, unstable, and unreliable.



I also have several years of experience reverse engineering code and have written assemblers / disassemblers before
Ghosuwa Wogomon 24-Oct-13 18:10pm View
Looks like a fail to me. None of the functions have the correct return type, ShowMouseRoll and ShowMouseLoc are sprintf'ing to a char which will throw an memory exception error, and DLLMain is just returning 1 instead of performing the conditional checking of the switch/case.

All of those were extremely simple functions, and yet your decompiler output complete trash that not only fails to do what the functions were originally intended to do, but will crash as well.

So I stick to my statement, decompiling is not possible.
Ghosuwa Wogomon 24-Oct-13 13:01pm View
no, it's not, for several reasons.

1. In assembly, arguments are pushed onto the stack by address to be passed to functions. There is no way to detect the type, size, or name of any of these arguments.

2. The above also applies to any variable in general. You have no way of knowing of esi is an integer, string, struct, function pointer, etc.

3. Even if you could get 1 and 2 out of the way (which you can't), compiler optimization would then get in your way. eg.
int i = 0, j = 0;
might be broken down to
xor ebx, ebx
xor ecx, ecx
locking 'i' and 'j' to 'ebx' and 'ecx' because they're commonly used, and there'd be no way for a decompiler to know if those are actual variables. another eg.
for (int i = 0; i < 3; i++)
Since this loop only has 3 cycles, the compiler might unroll, so instead of
mov ebp, 3
xor ebx, ebx
inc ebx
cmp ebx, 3
je .endForLoop
dec ecx
jmp .forLoop
it would become
add ebx, 3
add ecx, -3
There would be no way at all of knowing that the above is part of a for loop.


So, I reiterate, decompiling = impossible; disassembling = possible.