hi all,
i'm coding one dll, it contains one exported function. the name of the exported function is a base64
encoded string - base64 encoded strings have sometimes at the end one or two '=' characters (sometimes
without the '=' character(s)). this is the problem, masm doesn't want to compile the dll with the '='
in the name of exported function. so, my question is.. is it possible to compile a dll with '=' character
in the name of exported function?
my code (simplified) looks like this:
Library.def
LIBRARY Library
EXPORTS c3Vja2VkIG15IGNvY2s=
Library.asm
.486p
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
.code
dllentry proc hInstance:HINSTANCE, reason:DWORD, reserved1:DWORD
mov eax,TRUE
ret
dllentry Endp
c3Vja2VkIG15IGNvY2s= proc
nop
ret
c3Vja2VkIG15IGNvY2s= endp
End dllentry
for compilation i use a batch file that look like this:
@echo off
SET PROJECTNAME=Library
SET MASMBINPATH=\MASM32\BIN
%MASMBINPATH%\Cvtres.exe /nologo /machine:ix86 rsrc.res
%MASMBINPATH%\Ml.exe /nologo /Zp1 /c /coff %PROJECTNAME%.asm
%MASMBINPATH%\Link.exe /DLL /DEF:Library.def /SUBSYSTEM:WINDOWS /LIBPATH:\masm32\lib Library.obj
DEL *.obj
ECHO.
PAUSE
CLS
You can rename the function in the module definition file:
LIBRARY Library
EXPORTS "c3Vja2VkIG15IGNvY2s="=_foo@0
with
foo proc ; stdcall
nop
ret
foo endp
that seems pretty "sneaky" :(
Quote from: revolta on September 09, 2013, 04:57:11 PM
c3Vja2VkIG15IGNvY2s=
Firstly, congratulations.
Secondly, are you seriously naming your functions this way - and why?
LOL
If one will decode the string "c3Vja2VkIG15IGNvY2s=" from base64 to a binary, one will get the string "sucked my cock" :greensml:
Probably the topic is about the things that disallowed by the rulezzz of the forum :lol:
qWord: thx, will try it like that..
Tedd: definitelly, i am serious. :) i have to code dll files which names contains base64 strings. those base64 (encoded) strings can have at the end one, two or no zero (depends on the string that has to be coded to base64 form). these dll files are used for my reverse engineering project (cant say more about that). :)
Antariy: hey, that string is bogus one. it's the first that came on my mind.. when i was writing this question to this board. :D (it was required, that it should contain one or more '=')
Quote from: revolta on September 10, 2013, 04:52:09 PM
Antariy: hey, that string is bogus one. it's the first that came on my mind.. when i was writing this question to this board. :D (it was required, that it should contain one or more '=')
It was funny to find what the string actually is :biggrin:
Quote from: qWord on September 09, 2013, 06:11:06 PM
You can rename the function in the module definition file:
LIBRARY Library
EXPORTS "c3Vja2VkIG15IGNvY2s="=_foo@0
with
foo proc ; stdcall
nop
ret
foo endp
i've done these modifications.. but there's a problem, when i'm trying to compile it get an error:
Assembling: Library.asm
Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
Creating library Library.lib and object Library.exp
Library.exp : error LNK2001: unresolved external symbol "=_foo@0
Library.dll : fatal error LNK1120: 1 unresolved externals
how to fix this, pleeease?
Hi revolta,
Replacing Link.exe with Pelle's Polink.exe will solve the unresolved external symbol problem. The symbol = is a problem here :
c3Vja2VkIG15IGNvY2s= PROTO
My solution is to replace = with another symbol.
Download Gsar for Windows, it's a general search and replace utility :
http://gnuwin32.sourceforge.net/packages/gsar.htm
.386
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
includelib Base64Name.lib
c3Vja2VkIG15IGNvY2sx PROTO SYSCALL ; no symbol decoration
.code
start:
call c3Vja2VkIG15IGNvY2sx
invoke ExitProcess,0
END start
The problematic = symbol is replaced with x
\masm32\bin\ml /c /coff Base64Name.asm
\masm32\bin\polink /SUBSYSTEM:WINDOWS /DLL /DEF:Base64Name.def Base64Name.obj
\masm32\bin\ml /c /coff Test.asm
gsar.exe -o -sc3Vja2VkIG15IGNvY2sx -rc3Vja2VkIG15IGNvY2s= Test.obj
\masm32\bin\polink /SUBSYSTEM:WINDOWS Test.obj
gsar will modify the object file to replace sc3Vja2VkIG15IGNvY2sx with sc3Vja2VkIG15IGNvY2s=
Hi Erol,
good catch. :t
Gunther
Another method is to use Agner Fog's objconv tool to replace symbol names :
-nr:N1:N2 Replace symbol Name N1 with N2
\masm32\bin\ml /c /coff Base64Name.asm
\masm32\bin\polink /SUBSYSTEM:WINDOWS /DLL /DEF:Base64Name.def Base64Name.obj
\masm32\bin\ml /c /coff Test.asm
objconv -fcoff -nr:c3Vja2VkIG15IGNvY2sx:c3Vja2VkIG15IGNvY2s= Test.obj Test2.obj
\masm32\bin\polink /SUBSYSTEM:WINDOWS /OUT:Test.exe Test2.obj
Here is a valid export from slbiop.dll:
??4?$list@VFilePathComponent@iop@@V?$allocator@VFilePathComponent@iop@@@std@@@std@@QAEAAV01@ABV01@@Z
And that is not the worst case - try yourself (http://masm32.com/board/index.php?topic=2382.msg25024#msg25024) ::)
Jochen,
Quote from: jj2007 on September 26, 2013, 06:01:02 AM
Here is a valid export from slbiop.dll:
??4?$list@VFilePathComponent@iop@@V?$allocator@VFilePathComponent@iop@@@std@@@std@@QAEAAV01@ABV01@@Z
And that is not the worst case - try yourself (http://masm32.com/board/index.php?topic=2382.msg25024#msg25024) ::)
that's the famous and infamous name mangling and name decoration and it's a mess.
Gunther
MS VC++ has a specific name decoration convention :
http://en.wikipedia.org/wiki/Visual_C%2B%2B_name_mangling
Hi Erol,
Quote from: Vortex on September 27, 2013, 03:54:35 AM
MS VC++ has a specific name decoration convention :
http://en.wikipedia.org/wiki/Visual_C%2B%2B_name_mangling
sure, but that doesn't make it better.
Gunther
Hi Gunther,
I agree with you. Unfortunately, the name decorations can be very complicated and sharing object modules between different linkers can be difficult because of this.
Hi Erol,
Quote from: Vortex on September 28, 2013, 04:46:15 AM
I agree with you. Unfortunately, the name decorations can be very complicated and sharing object modules between different linkers can be difficult because of this.
that's the crucial point. Some schemes doesn't fit together.
Gunther
An interesting article :
http://wyw.dcweb.cn/stdcall.htm
Erol,
thank you for the information. It could be helpful in some cases.
Gunther
thx to all. i decided to make some research about this issue.. i found out that it is enough to rename the
name of the exported function in the export pe section (in this case .rdata). it is needed to find the name
of the exported function in the export directory in PE and put to the end of the name string the "="
character ("c3Vja2VkIG15IGNvY2s" -> "c3Vja2VkIG15IGNvY2s="). when this patch is done, the api GetProccAddress
finds the function as "c3Vja2VkIG15IGNvY2s=".
.def
LIBRARY Library
EXPORTS c3Vja2VkIG15IGNvY2s
.asm
.486p
.model flat, stdcall
option casemap:none
include \masm32\include\kernel32.inc
include \masm32\include\windows.inc
includelib \masm32\lib\kernel32.lib
.const
NameOfLibrary db "Library.dll", 0
.code
dllentry proc hInstance:HINSTANCE, reason:DWORD, reserved1:DWORD
mov eax,TRUE
;========================================PATCH========================================
pushad ;save registers onto stack
invoke GetModuleHandleA,offset NameOfLibrary ;get imagebase of Library.dll
movzx edx,word ptr ds:[eax+3ch] ;get offset of PE header to EDX
add edx,eax ;add offset of PE header with imagebase, get VA of PE header
mov edx,dword ptr ds:[edx+78h] ;get offset of Export Table (Export Directory)
add edx,eax ;add offset of Export Table (Export Directory) with imagebase, get VA
mov edx,dword ptr ds:[edx+20h] ;get offset of AddressOfNames
add edx,eax ;add offset of AddressOfNames with imagebase, get VA
mov edx,dword ptr ds:[edx] ;get name of the exported function
add edx,eax ;add offset of name of the exported function with imagebase, get VA
push edx ;start address of exported function name put do EDI
pop edi ;start address of exported function name put do EDI
xor ecx,ecx ;clear ECX - put into ECX the maximal counter (0ffffffffh)
dec ecx ;clear ECX - put into ECX the maximal counter (0ffffffffh)
xor eax,eax ;clear EAX - we have to have the AL cleared, the AL will be searched
repne scasb ;find AL (00h) from the starting address of the exported function name - i.e. find the first zero byte at the end of the name of the exported function - we can put there the "=" character
dec edi ;get back one byte
push NULL
invoke VirtualProtect,edi,TRUE,PAGE_READWRITE,esp ;we have to change the access protection of the byte we wanna patch
pop ecx
mov byte ptr ds:[edi],'=' ;put there the "=" character
popad ;restore the registers from the stack
;========================================PATCH========================================
ret
dllentry Endp
;==============================CODE_OF_EXPORTED_FUNCTION==============================
c3Vja2VkIG15IGNvY2s proc
nop
ret
c3Vja2VkIG15IGNvY2s endp
;==============================CODE_OF_EXPORTED_FUNCTION==============================
End dllentry
you may be able to get the proc address using an ordinal, rather than a long string
Hi revolta,
Nice solution but if there is more than one modification, you must take in account the alphabetical order of the exported symbols.