Btw...If someone wants to see the src code, open the file in RosAsm and search for the function "GetFullUndecorate". It is located under the TITLE tab "PUBLICSYMBOLPARSING"
Proc GetFullUndecorate:
Arguments @ptrSymbol, @pDecoratedName, @pOutput, @LiteralStrType
Local @OriginalStringLen, @pCRCValue
Uses edi, esi, ecx, edx, ebx
mov esi D@pOutput
mov edi D@pDecoratedName
..If_And D$edi = '??_C', W$edi+4 = '@_' ; <--------- Parser of literal strings symbols. (This is the signature for the literal symbol)
lea ebx D@OriginalStringLen | mov D$ebx 0
lea ecx D@pCRCValue | mov D$ecx 0
call LiteralSringUndecorate edi, Sz_Symbol_Temp, ebx, ecx, D@LiteralStrType
mov D$esi+CDiaBSTR.SzSymbolNameDis Sz_Symbol_Temp
mov D$esi+CDiaBSTR.SymbolLenDis eax
..Else ; <--------- Parser of regular symbols with MsDia Api
call GetUndecoratedSymbolName esi, D@ptrSymbol
mov ecx D$UndecoratedName.Len
mov edx D$UndecoratedName.Name
..End_If
EndP
The function below is my decoder of literal strings (char and wchar types). I ommited here the rest of the functions, because it have several routines. See the embeded source opening the file in RosAsm to analyse it.
;;
??_C@_17CKCOCGAB@?$AAC?$AAf?$AAm?$AA?$AA@
??_C@_ = String token
1 = char type 0 = char, 1 = wchar_t (non negative integer)
7 = string len including the null termination byte
CKCOCGAB@ = CRC
?$AAC = s
?$AAf = t
?$AAm = (
?$AA = 4 065 04
?$AA@ = )
;;
; the len of undecorated string in eax. If 0 the functyion fails.
;;
Refs:
http://www.geoffchappell.com/studies/msvc/language/decoration/strings.htm?tx=14,16
calling_conventions.pdf
http://agner.org/optimize/calling_conventions.pdf
;;
Proc LiteralSringUndecorate:
Arguments @pInString, @pOutput, @pOriginalStringLen, @pCRC, @LiteralStrType
Local @IsUnicode, @StringLiteralFormErr
Uses esi, edi, ecx, ebx
mov esi D@pInString
mov edi D@pOutput
mov D@IsUnicode &FALSE
xor eax eax
If_And D$esi <> '??_C', W$esi+4 <> '@_'
ExitP
End_If
; bypass literal token "??_C@_"
mov ebx D@LiteralStrType
add esi 6
If B$esi = '1'
mov D$ebx LITERAL_STRING_WCHAR
mov D@IsUnicode &TRUE
Else_If B$esi <> '0' ; The literal string format is unknown. Return 0 if failure
mov D$ebx LITERAL_STRING_CHAR
mov eax 0 | ExitP
Else
mov D$ebx LITERAL_STRING_CHAR
End_If
inc esi ; bypass unicode/ascii check
; calculate original len of the string
mov ebx D@pOriginalStringLen
..If_And B$esi >= '0', B$esi <= '9'
movzx eax B$esi
sub al '0' | mov D$ebx eax
inc esi ; bypass the len, and go to start of CRC. (On this case, the CRC is not preceeeded with '@' char)
..Else
;1st we check the lenght of the "len" seeking for the next '@' char
mov edx esi
xor ecx ecx
While B$edx+ecx <> '@'
inc ecx
On ecx > 8, jmp L1> ; for safety, if len if bigger then 8, exit loop
End_While
L1:
.If_Or ecx = 0, ecx > 8 ; No len token '@'. Error
xor eax eax | ExitP
.Else
lea edx D@StringLiteralFormErr | mov D$edx 0
call LiteralAsciiBaseEx esi, ecx, BASE_HEX, edx
If D@StringLiteralFormErr = &FALSE ; The format of CRC is incorrect. Exit
xor eax eax | ExitP
Else
mov D$ebx eax
End_If
.End_If
add esi ecx ; got to the end of the "len" string
inc esi ; bypass '@' char and go to the start of CRC
..End_If
; Now we compute the CRC.
; 1st we check the len of the string related to the CRC
mov edx esi
xor ecx ecx
While B$edx+ecx <> '@'
inc ecx
On ecx > 8, jmp L1> ; for safety, if len if bigger then 8, exit loop
End_While
L1:
.If_Or ecx = 0, ecx > 8 ; No ending CRC token '@'. Error
xor eax eax | ExitP
.Else
mov ebx D@pCRC
lea edx D@StringLiteralFormErr | mov D$edx 0
call LiteralAsciiBaseEx esi, ecx, BASE_HEX, edx
If D@StringLiteralFormErr = &FALSE ; The format of CRC is incorrect. Exit
xor eax eax | ExitP
Else
mov D$ebx eax
End_If
.End_If
add esi ecx ; got to the end of the "CRC" string
inc esi ; bypass '@' char and go to the start of data
If D@IsUnicode = &TRUE ; const wchar_t
call DemangleLiteralUnicodeString esi, edi
Else ; const char
call DemangleLiteralCharString esi, edi
End_If
EndP
decoder of the "A" to "P" table (A replacement of the regular inttohex conversions
; used for tables "A" to "P". Len is bigger then 9
;;
Dec Hex Literal
0 0 A
1 1 B
2 2 C
3 3 D
4 4 E
5 5 F
6 6 G
7 7 H
8 8 I
9 9 J
10 A K
11 B L
12 C M
13 D N
14 E O
15 F P
;;
; this function does not include the null termination byte
Proc LiteralAsciiBaseEx:
Arguments @String, @StringLen, @Base, @pErr
Uses esi, ebx, ecx, edi
mov esi D@String, eax 0, ebx 0
mov ecx D@StringLen
mov edi D@pErr | mov D$edi &TRUE
While ecx <> 0
mov eax ebx | mul D@Base | mov ebx eax, eax 0
mov al B$esi
If_And al >= 'A', al <= 'J'
sub al 'A' | add al '0'
Else_if_And al >= 'K', al <= 'P'
sub al 'K' | add al 'A'
Else
xor eax eax
mov D$edi &FALSE | ExitP
End_If
sub al '0'
; Cases of Hexa Notation:
On al > 9, sub al 7
add ebx eax | inc esi
dec ecx
End_While
mov eax ebx
EndP
The function below shows the normal symbols under MSDia
Proc GetUndecoratedSymbolName:
Arguments @pCDiaBSTR, @ptrSymbol
Local @bstrName
Uses esi, ecx, ebx, edx, edi
mov edi D@pCDiaBSTR
mov D$edi+CDiaBSTR.SzSymbolNameDis 0
mov D$edi+CDiaBSTR.SymbolLenDis 0
mov D@bstrName 0
lea ebx D@bstrName
icall DIA_SYMBOL_GET_UNDECORATEDNAMEEX D@ptrSymbol, &UNDNAME_COMPLETE, ebx
.If eax = &S_OK
call WriteTempSymbol D@pCDiaBSTR, D@bstrName
mov eax &TRUE
.Else
xor eax eax
.End_If
EndP