I am trying to test different obfuscators. Before obfuscating I used Reko decompiler. It seems that the exe is already obfuscated - please look at the screen shot. Can someone please explain - why all the methods and variables seems as if the exe is already obfuscated?
Symbol names are not compiled into executable machine code.
They can be preserved, but in this case they are saved in separate .pdb file. If you don't generate it during build, or don't make available to debugger/decompiler, it cannot figure out variables and function names (except for the imported/exported ones)
High level constructs, like for or while are implemented with jumps and conditional jumps, so it is not possible to figure out if a loop was implemented via for or goto or if a conditional was if statement or ternary operator.
Optimization hugely transforms code, throwing away unnecessary parts, making some operations at compile time, etc.
Related
I have a #define ONB in a c file which (with several #ifndef...#endifs) changes many aspects of a programs behavior. Now I want to change the project makefile (or even better Makefile.am) so that if ONB is defined and some other options are set accordingly, it runs some special commands.
I searched the web but all i found was checking for environment variables... So is there a way to do this? Or I must change the c code to check for that in environment variables?(I prefer not changing the code because it is a really big project and i do not know everything about it)
Questions: My level is insufficient to ask in comments so I will have to ask here:
How and when is the define added to the target in the first place?
Do you essentially want a way to be able to post compile query the binaries to to determine if a particular define was used?
It would be helpful if you could give a concrete example, i.e. what are the special commands you want run, and what are the .c .h files involved?
Possible solution: Depending on what you need you could use LLVM tools to maybe generate and examine the AST of your code to see if a define is used. But this seems a little like over engineering.
Possible solution: You could also use #includes to pull in .c or header files and a conditional error be generated, or compile (to a .o), then if the compile fails you know it is defined or not. But this has it's own issues depending on how things are set-up in your make file.
Basically, when declaring Windows API functions in my VB6 code, there comes with these many constants that need to be declared or used with this function, in fact, usually most of these constants are not used and you only end up using one of them or so when making your API calls, so I am using Conditional Compilation Arguments to exclude these (and other things) using something like this:
IncludeUnused = 0 : Testing = 1
(this is how I set two conditional compilation arguments (they are of Boolean type by default).
So, many unused things are excluded like this:
#If IncludeUnused Then
' Some constant declarations and API declarations go here, sometimes functions
' and function calls go here as well, so it's not just declarations and constants
#End If
I also use a similar wrapper using the Testing Boolean declared in the Conditional Compilation Argument input field in the VB6 Properties windows "Make" tab. The Testing Boolean is used to display message boxes and things like that when I am in testing mode, and of course, these message boxed are removed (not displayed) if I have Testing set to 0 (and it is obviously 1 when I am Testing).
The problem is, I tried setting IncludeUnused and Testing to 0 and 1 and visa versa, a total of four (4) combinations, and no matter what combination I set these values to, the output EXE file size for my VB6 EXE does not change! It is always 49,152 when compiled to Native Code using Fast Code, and when using Small Code.
Additionally, if I compile to p-code under the four (4) combinations of Testing and IncludeUnused, i always end up with the file size 32,768 no matter what.
This is driving me crazy, since it is leading me to believe that no change is actually occuring, even though it is. Why is it that when segments of code are excluded from compilation, the file size is still the same? What am I missing or doing wrong, or what have I miscalculated?
I have considered the option that perhaps VB6 automatically does not compile code which is not used into the final output EXE, but I have read from a few sources that this is not true, in that, if it's included, it is compiled (correct me if I am wrong), and if this is right, then there is no need to use the IncludeUnused Boolean to remove unused code...?
If anyone can shed some light on these thoughts, I'd greatly appreciate it.
It could well be that the size difference is very small and that the exe size is padded to the next 512 or 1024 byte alignment. Try compressing the exe's with zip and see if the zip-file sizes differ.
You misunderstand what a compiler does. The output of the VB6 compiler is code. Constants are merely place holders for values, they are not code. The compiler adds them to its symbol table. And when it later encounters a statement in your code that uses the constant then it replaces the constant by its value. That statement produces the exact same code whether you use a constant or hard-code the value in the statement.
So this automatically implies that if you never actually use the constant anywhere then there is no difference at all in the generated code. All that you accomplished by using the #If is to keep the compiler's symbol table smaller. Which is something that makes very little sense to do, the actual gain from compilation speed you get is not measurable. Symbol tables are implemented as hash tables, they have O(1) amortized complexity.
You use constants only to make your code more readable. And to make it easy to change a constant value if the need ever arises. By using #If, you actually made your code less readable.
You can't test runtime data in conditional compilation directives.
These directives use expressions made up of literal values, operators, and CC constants. One way to set constant values is:
#Const IncludeUnused = 0
#Const Testing = 1
You can also define them via Project Properties for IDE testing. Go to the Make tab in that dialog and click the Help button for details.
Perhaps this is where you are setting the values? If so, consider this just additional info for later readers rather than an answer.
See #If...Then...#Else Directive
VB6 executable sizes are padded to 4KB blocks, so if the code difference is small it will make no difference to the executable.
I am wondering what difference it makes to the debugger (Intellij IDEA + Scala plug-in) when I debug Scala code and not Java code. To my understanding, a debugger is tightly coupled with the language i.e. a Java debugger can not handle Scala code but apparently the JVM is the center of attention here meaning as long as it is byte-code, any debugger would do. right ?
IMPORTANT UPDATE: The problem was to give an example of how a byte-code debugger may be limiting for Scala. Assume a break point is reached and I don't want to go to the next line but I want the debugger to evaluate an Scala expression in the context of the application (e.g. I like to call an operator method from a singleton object). The debugger is stuck because it can not understand Scala. I have to do the transformation myself and input the resulting Java to the debugger.
The problem is that only "breakpoint stuff" could be handled in byte-code level. What if you want to put an expression under watch? Debugger has to understand Scala to evaluate the watched expression,right? This time I'm sure I'm right. Vengeance is mine, Saith the Lord ;-)
Short answer your assumptions are wrong.
The reason is the debugger does not care what language your debugging. It stops at breakpoints which in turn include the line of a particular source file. Note that the source file is merely text for you to read - the debugger never scans the source files. If you change the spot where source files are to another directory with a text file in the right directory w/ the right filename as a breakpoint that has been set, the debugger will happily show it when the breakpoint happens. Everytime you set a breakpoint your ide is telling the debugger hey scan this class for any byte code on this line and stop when you hit it. This of course does not work if your ide is attempting to compile the same text file into a class file - however it will work if you create fake text files as source for a jar file and do the source file mapping thing.
If one thinks about it, writing a simple template and compiling it while support debugging is not that difficult. Simply use asm to create all the print statements and tell asm this print statement is from the template file on this line. After that you can add more clever stuff while keeping things debuggable.
Maybe asking the question betrays my lack of knowledge about the process, but then again, there's no better reason to ask!
Tracking these down can be frustrating because stack traces can help me know where to start looking but not which object was null.
What is going on under the hood here? Is it because the variable names aren't bundled in the executable?
.NET code built with full optimizations and no debug info: your local variable names are gone, some local variables may have been eliminated entirely.
.NET code built with full optimizations + PDB (or full debug): most local variable names preserved, some local variables may have been eliminated
No optimizations + no debug info: local variable names are gone.
And then we have to consider that whatever you're dealing with may not be in a local variable at all - it might have been the result of a previous function call, on which you're chaining a new function call.
Basically you answered your own question. When you're code is compiled it's transformed in intermediate language (IL). IL does not have variable names the way your code does, arguments to a method being called are pushed on to a stack before the method is called and the currents methods arguments and local variables are referred to by there position. I believe this is because this structure aids the JIT compiler generate code.
The pdb symbols file stores a mapping between the IL generated and your code. It is used to tell you which line in your code each method call in the call stack refers to. Possibly the information stored here isn't detailed enough to say which variable is null, or possibly it was just considered too expensive in terms when of perf to be able to do this. In any case, if you have allowed the compiler to optimize the IL generated there may no longer be a one to one mapping between the variables in the IL and the variables in your code.
Hope that helps,
Rob
There is no "object identifier". There's no way that .NET could say "the object with identifier xxxx is null".
You'll learn how to not make these mistakes, don't worry. Just break down your expressions into smaller pieces, and you'll find which objects you forgot to initialize. You'll learn to iniitialize them in that scenario, and after a while, that case won't happen again.
I am using MSVC 6.0 to call a macro in the Win32API and I'm getting an access violation. I know that the pointers I'm passing to the macro contain valid addresses, though they're evidently not pointing to the correct data.
The macro accepts multiple pointers, and I'm not sure which pointer is erroneous, so I'd like to use MSVC's debugger to 'step into' the macro to see exactly where the problem is. When I've tried thus far, the debugger just throws the access violation error.
Is it possible to 'step into' a macro using MSVC 6.0's debugger? If not, is there anyway for me to check what the macro expands to, so I can get a better idea of what I'm not doing correctly?
If you really need to trace the macro code, the only way would be to find the definition of the macro, manually "instantiate" the macro code (substituting the parameters) in place where it is "called", and then trace it in the debugger as ordinary code.
Alternative variant would be to step through the disassembly, if your skill level is sufficient to back-associate the disassembled code with the original macro code.
You cannot step into the macro because at the point compiler does its job, the macro is already expanded. However, you can step through a macro - if you just do "step", you will actually step through all code inside the macro as if it was expanded, line by line. If you to "step into", you will step into every function call made from that macro. If the macro is small enough, and/or you know it very well, you can do a "blind step through" that way.
You can step into functions that are called from the macro but as far as I know can not really step through the macro lines themselves. And yes if you code compiles - you can find the macro definition (use MSVC function/class browser to find where it is defined, some header file probably)
I'd just step into the disassembly - usually, even if you're not an assembly expert, short runs of code (a few lines) the assembly map back to the C/C++ code pretty readily (especially in non-Release builds). Hopefully the macro isn't so hairy that that isn't the case here.
Remember that plenty of debugging occurs even without source code, so having the source and the disassembly together usually isn't too bad. And if it's something you haven't much experience with, it's great experience to get.