flat assembler
Message board for the users of flat assembler.
Index
> Windows > Export by ordinals only |
Author |
|
l_inc 09 Feb 2013, 21:18
nmake
Quote: It works, but I am not sure if it is correct, can anyone confirm the correct method of exporting functions in a dll by ordinals only? This is not correct. This way you just export a weird-named function (empty-named in your case). Here's a macro able to export by ordinals. It also provides control for repeated ordinals. But be advised, that if you specify ordinal values dispersed over a wide numeric range, then you'll get quite a large export table. Btw. what's the purpose of exporting by ordinal only? |
|||
09 Feb 2013, 21:18 |
|
nmake 09 Feb 2013, 21:58
l_inc wrote: nmake If you get addresses of your exported functions directly through getprocaddress then you don't need the function names, it also adds another indirect layer. Function names give off clue to the nature of what a function do, cutting away names give debuggers a harder time guessing what it does. Having names in an important dll is like putting labels on the door of your safe where you keep your gold, a note where it says "Come on in here, steal my gold right away" |
|||
09 Feb 2013, 21:58 |
|
l_inc 09 Feb 2013, 22:11
nmake
Quote: If you get addresses of your exported functions directly through getprocaddress You don't have to import with GetProcAddress in order to import by ordinal. The standard import macro is able to handle ordinals instead of names. Quote: Function names give off clue to the nature of what a function do, cutting away names give debuggers a harder time guessing what it does. I'm pretty sure that debuggers don't try to guess the functionality from function names. Regarding reverse engineers I'd say, that if someone needs to reverse engineer your dll, hiding exported names is of no effect. Besides, you could use any randomly generated export name. At least you wouldn't have to pay attention on ordinal inconsistencies between the versions of your dll's in this case. |
|||
09 Feb 2013, 22:11 |
|
nmake 09 Feb 2013, 22:18
l_inc wrote: nmake That is only true if you know the dll in and out, if you intend to share it, thats not always the case. But I am not talking about multiple ways of importing it, I am only mentioning the standard, default way. l_inc wrote:
And you're right, debugger's as the reverse engineer , not the debugger itself. l_inc wrote:
It has a huge effect, especially if the dll is large, and the reverser have a huge task ahead of him, having a huge list of names makes the difference between alpha and omega. I think maybe you are confusing normal breakpoints, tracing and general debugging with functionality of the code. You can easily track code, but you cannot easily tell what it does without going deeper into the code, perhaps it has a bitfield and you don't know anything about what each bit does, then having a function name will reveal what it does. I think maybe you are thinking of breaking protection schemes, like nop'ing out small bits here and there, that's easy without function names, but if you are a serious reverse engineer, going out to change the functionality of a program, then you need more tools at hand, an evergrowing need for more information, more information is always better. Serious reverse engineers doesn't just nop out instructions here and there, they change the entire functionality of a program, even create their own library to add to the program. Last edited by nmake on 09 Feb 2013, 22:36; edited 3 times in total |
|||
09 Feb 2013, 22:18 |
|
HaHaAnonymous 09 Feb 2013, 22:21
[ Post removed by author. ]
Last edited by HaHaAnonymous on 28 Feb 2015, 21:35; edited 2 times in total |
|||
09 Feb 2013, 22:21 |
|
nmake 09 Feb 2013, 22:23
Removing function names is not a protection method, it is just another daily routine. Those of you who think it is, perhaps you assume badly, it is just routine work and it is effortless to do in other assemblers that I've used, but in fasm I have to get used to the different macros available.
It is very simple math: Function ordinal = 10 (Reverse engineer spend 30 minutes to figure out what the code is doing) Function name = SendEncryptedMessage (reverse engineer saves 20 minutes) Library has got 150 functions and can finish his work in a third of the time. |
|||
09 Feb 2013, 22:23 |
|
l_inc 09 Feb 2013, 22:51
nmake
Quote: perhaps it has a bitfield and you don't know anything about what each bit does, then having a function name will reveal what it does You don't have an exported function for every bit of every bitfield, do you? And that's the point. The percentage of the exported functions is normally very low compared to the total code size. Quote: but in fasm I have to get used to the different macros available Oh, that's quite questionable, because the macro I provided has almost the same interface as the standard macro (just use two commas instead of one to omit the function name and to specify the ordinal). So, I'd say, getting used to the macro is effortless. Getting used to the syntax of the DEF-files is kinda problem.[/i] |
|||
09 Feb 2013, 22:51 |
|
nmake 09 Feb 2013, 22:55
l_inc wrote: Besides, you could use any randomly generated export name. At least you wouldn't have to pay attention on ordinal inconsistencies between the versions of your dll's in this case. There is a fine reason why names is an entity in programming, be sure to remind me what purpose your encrypted function names is going to have. Whatever the purpose it is going to have, it is not to identify something, but to obfuscate, which proves my point, that if you don't need them you don't need them, and especially not if you intend to encrypt function names like you imply here. The purpose of a name or a label is to be able to identify something, encrypted names is not usable to anything. |
|||
09 Feb 2013, 22:55 |
|
nmake 09 Feb 2013, 22:59
l_inc wrote:
It depends on your experience in reverse engineering, I can only talk from my own experience, and I've seen many times that large programs ship with tiny functions, a lot of them, very tiny functions exported. More information is better to a reverse engineer, always. l_inc wrote: Getting used to the syntax of the DEF-files is kinda problem.[/i] I have used definition files with masm for years and I know them in and out, it's very easy. |
|||
09 Feb 2013, 22:59 |
|
l_inc 09 Feb 2013, 23:07
nmake
Quote: Whatever the purpose it is going to have, it is not to identify something, but to obfuscate You seem to not understand the difference between the exported name and a name used in your source codes. The purpose of the exported name is not identification by a human, but by an importing program. Ordinals in turn are nothing more than a position in an array. The advantage of exporting by name is therefore to be able to abstract from the array positions. So that you for example do need an array of 1000 elements when exporting just two functions. |
|||
09 Feb 2013, 23:07 |
|
nmake 09 Feb 2013, 23:13
l_inc wrote: nmake The guy who is going to use your library will take advantage of the importing program or loader, but he will have to get familiar with the names before using the library, even though the loader uses the names, it ultimately is the programmer who is dependent on the names. So I strongly disagree with you. l_inc wrote:
Well, what ordinals are and are not is not that relevant, it is just a number used to relate to an address, as long as it serves the purpose of replacing names, I think that the definition of what ordinals are is uninteresting. |
|||
09 Feb 2013, 23:13 |
|
l_inc 09 Feb 2013, 23:31
nmake
Quote: but he will have to get familiar with the names before using the library, even though the loader uses the names, it ultimately is the programmer who is dependent on the names The guy will be getting familiar with the names, he will be using in his source codes, not with the names, exported from the dll binary. Just look what (mangled) names are used in C++ static libraries and try to get familiar with _ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_PKcS4_ . Or have you tried to import COM-objects? What matters there is a guid. You're not getting familiar with DEBBD32E-1D08-4F6A-8A26-E1B3D768A1E5. You're getting familiar with names, specified in the headers. Quote: it is just a number used to relate to an address It is a number, that has an important collateral impact on your binary. Just try to use the macro I provided to export one function with the ordinal 1 and one function with the ordinal 100000 from a very simple dll. Quote: as long as it serves the purpose of replacing names, I think that the definition of what ordinals are is uninteresting The point is that it serves worse, than a function name, even an obfuscated one. |
|||
09 Feb 2013, 23:31 |
|
nmake 10 Feb 2013, 01:18
The added bits of information is not mandatory, but usually you can read the calling convention at the beginning followed by the name and size of the parameters. GUID is not mandatory and the names are still relevant to the programmer, the programmer doesn't deal with GUID's, the idea of that is insane in itself
|
|||
10 Feb 2013, 01:18 |
|
l_inc 10 Feb 2013, 15:25
nmake
Quote: The added bits of information is not mandatory To my knowledge those are mandatory. This is the way the C++ cross-unit type checking works. If you don't have mangled names, then it's not C++. Quote: but usually you can read the calling convention at the beginning followed by the name and size of the parameters You're confusing C++ name mangling with simple C name decoration. Quote: GUID is not mandatory and the names are still relevant to the programmer GUID is mandatory unless you are creating an object of a well-known predetermined type. For any third-party objects registered in the registry you will need it's class identifier (and interface identifier), i.e. a GUID, to pass into the CoCreateInstance. Quote: the programmer doesn't deal with GUID's, the idea of that is insane in itself See the usecom.asm example from the fasm package. |
|||
10 Feb 2013, 15:25 |
|
nmake 10 Feb 2013, 17:22
The whole point is that the programmer doesn't use GUID to refer to function names. It's just an underlying layer, it would be too much to remember 128 bit numbers like you seem to suggest. Name convention stays the same despite the underlying GUID system so I have to disagree with you again.
And I might also add that despite the GUID system uses the exported names, doesn't mean function names were designed for GUID, it's just that GUID takes advantage of names, in fact it's the other way around, names were designed for identification by the programmer. Things evolved, but they didn't evolve for you to redefine the original purpose. |
|||
10 Feb 2013, 17:22 |
|
l_inc 10 Feb 2013, 18:39
nmake
Quote: The whole point is that the programmer doesn't use GUID to refer to function names. The fact is that this is also my point. What is specified as an exported name in your dll binary does not necessarily needs to be the function name, that you use in your source codes to define or call the function. This makes the exported name to be nothing more, than such "an underlying layer". And therefore export by ordinal only or import by ordinal does not make much sense for your case. |
|||
10 Feb 2013, 18:39 |
|
nmake 10 Feb 2013, 21:26
I'd prefer to loop from ecx=1 to ecx=10 than looping from StrToInt(1)..StrToInt(10)
It still makes sense to me. |
|||
10 Feb 2013, 21:26 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.