unmangler 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.gitignore +4 -0
- data/lib/unmangler.rb +6 -4
- data/lib/unmangler/base.rb +27 -0
- data/lib/unmangler/borland.rb +109 -128
- data/lib/unmangler/msvc.rb +1025 -0
- data/lib/unmangler/string_ptr.rb +26 -1
- data/lib/unmangler/version.rb +1 -1
- data/spec/borland_samples_spec.rb +28 -0
- data/spec/borland_spec.rb +2 -0
- data/spec/msvc_samples_spec.rb +28 -0
- data/spec/msvc_spec.rb +61 -0
- data/spec/samples_spec.rb +51 -0
- data/spec/spec_helper.rb +31 -6
- data/unmangler.gemspec +3 -1
- metadata +12 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NTMyYTYwYzU4MDAwYWMxZmQxOTFmYzhmMjA1YjAyZmViYmJjOWJhYw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
OWE2NmRhMjY2MGZkN2UxMDI4MDliYTBmZTY0NThlMDlmOWE4MDU5ZQ==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NWQwNmIzN2YyN2UwYjE4OWZiY2IxMDdhNzI2YjAyOGE1YzQ4NDE3NWU5YmNi
|
10
|
+
NzA0NDk4ODc0NDM2MTYwZTIzNmMyZTFhYmY3ZmJkYWUwMjhlODEzNGM3OTQx
|
11
|
+
ODUyMDM3ODdkMzNkNmYyMGMzODEyYTA3OGY5NGMxMjJjZmMwY2Q=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NThiMGEzM2NkMTY5YWZmYzA2MTE2YjIwMzlkYjU5NzIzYzE5N2IxYzg5NzI3
|
14
|
+
YWVhOTQ1M2EzZWMyN2QzMmE0NTlmYzBiZjViOWE2NjUzNjIxOWRjY2U3OGQ1
|
15
|
+
MDcwMTM5MTJiOWM1ZjgyYTkyNDc4N2JlNzhmNWUxOTQ4N2M2Yzk=
|
data/.gitignore
CHANGED
data/lib/unmangler.rb
CHANGED
@@ -1,19 +1,21 @@
|
|
1
|
+
require 'unmangler/string_ptr'
|
2
|
+
require 'unmangler/base'
|
1
3
|
require 'unmangler/version'
|
2
4
|
require 'unmangler/borland'
|
5
|
+
require 'unmangler/msvc'
|
3
6
|
|
4
7
|
module Unmangler
|
5
8
|
class << self
|
6
9
|
def unmangle name, args={}
|
7
|
-
if name[0
|
10
|
+
if name[0] == "@"
|
8
11
|
Unmangler::Borland.safe_unmangle name, args
|
9
12
|
# TODO: check if result is same as input
|
10
13
|
# and try to unmangle with MS if it is
|
14
|
+
elsif name[0] == '?'
|
15
|
+
Unmangler::MSVC.safe_unmangle name, args
|
11
16
|
elsif name[0,2] == '_Z'
|
12
17
|
# GCC ?
|
13
18
|
name
|
14
|
-
elsif name[0,1] == '?'
|
15
|
-
# MS ?
|
16
|
-
name
|
17
19
|
else
|
18
20
|
# return original name
|
19
21
|
name
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Unmangler
|
2
|
+
class Base
|
3
|
+
def isdigit c
|
4
|
+
c =~ /\A\d\Z/
|
5
|
+
end
|
6
|
+
|
7
|
+
def assert cond
|
8
|
+
raise unless cond
|
9
|
+
end
|
10
|
+
|
11
|
+
# same as 'unmangle', but catches all exceptions and returns original name
|
12
|
+
# if can not unmangle
|
13
|
+
def safe_unmangle name, *args
|
14
|
+
unmangle name, *args
|
15
|
+
rescue
|
16
|
+
name
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.unmangle *args
|
20
|
+
new.unmangle(*args)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.safe_unmangle *args
|
24
|
+
new.safe_unmangle(*args)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/unmangler/borland.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'unmangler/string_ptr'
|
2
|
+
require File.expand_path("base", File.dirname(__FILE__))
|
4
3
|
|
5
4
|
# ported from Embarcadero RAD Studio XE3
|
6
5
|
# $(BDS)\source\cpprtl\Source\misc\unmangle.c
|
@@ -9,7 +8,7 @@ require 'unmangler/string_ptr'
|
|
9
8
|
|
10
9
|
module Unmangler; end
|
11
10
|
|
12
|
-
class Unmangler::Borland
|
11
|
+
class Unmangler::Borland < Unmangler::Base
|
13
12
|
attr_accessor :kind
|
14
13
|
|
15
14
|
UM_UNKNOWN = 0x00000000
|
@@ -57,11 +56,6 @@ class Unmangler::Borland
|
|
57
56
|
|
58
57
|
MAXBUFFLEN = 8192 # maximum output length
|
59
58
|
|
60
|
-
# The mangler, when mangling argument types, will create
|
61
|
-
# backreferences if the type has already been seen. These take the
|
62
|
-
# form t?, where ? can be either 0-9, or a-z.
|
63
|
-
|
64
|
-
|
65
59
|
# New mangle scheme lengths:
|
66
60
|
# len == 254 ==> old hash
|
67
61
|
# len == 253 ==> new MD5 hash
|
@@ -86,6 +80,7 @@ class Unmangler::Borland
|
|
86
80
|
end
|
87
81
|
|
88
82
|
def copy_char c
|
83
|
+
#puts "[d] copy_char #{c.inspect} from #{caller[0]}"
|
89
84
|
@target[0] = (c == 0 ? "\x00" : c)
|
90
85
|
@target.inc!
|
91
86
|
end
|
@@ -131,11 +126,13 @@ class Unmangler::Borland
|
|
131
126
|
"rand"=> "&=", "rdiv"=> "/=", "rlsh"=> "<<=","rmin"=> "-=", "rmod"=> "%=",
|
132
127
|
"rmul"=> "*=", "ror" => "|=", "rplu"=> "+=", "rrsh"=> ">>=","rsh" => ">>",
|
133
128
|
"rxor"=> "^=", "subs"=> "[]", "sub" => "-", "xor" => "^", "arow"=> "->",
|
134
|
-
"nwa" => "new[]", "dele"=> "delete", "dla" => "delete[]"
|
129
|
+
"nwa" => "new[]", "dele"=> "delete", "dla" => "delete[]",
|
130
|
+
# not in unmangle.c, but from IDA
|
131
|
+
"cctr" => "`class constructor`", "cdtr" => "`class destructor`"
|
135
132
|
}
|
136
133
|
|
137
134
|
def copy_op src
|
138
|
-
copy_string(OPS[src] || src)
|
135
|
+
copy_string(OPS[src] || "?#{src}?")
|
139
136
|
end
|
140
137
|
|
141
138
|
def copy_return_type(start, callconv, regconv, process_return)
|
@@ -170,7 +167,7 @@ class Unmangler::Borland
|
|
170
167
|
# string, it means the location of all the qualifier names is
|
171
168
|
# about to move.
|
172
169
|
|
173
|
-
|
170
|
+
if @adjust_quals
|
174
171
|
@namebase += ret_len if @namebase
|
175
172
|
@qualend += ret_len if @qualend
|
176
173
|
@prevqual += ret_len if @prevqual
|
@@ -182,13 +179,12 @@ class Unmangler::Borland
|
|
182
179
|
def copy_type(start, arglvl)
|
183
180
|
start = start.dup if start.is_a?(StringPtr)
|
184
181
|
|
185
|
-
tname
|
182
|
+
tname = buff = nil
|
186
183
|
c = input()
|
187
184
|
is_const = false
|
188
185
|
is_volatile = false
|
189
186
|
is_signed = false
|
190
187
|
is_unsigned = false
|
191
|
-
maxloop = 101
|
192
188
|
savedsavechar = nil
|
193
189
|
|
194
190
|
arglvl =
|
@@ -197,6 +193,7 @@ class Unmangler::Borland
|
|
197
193
|
else true
|
198
194
|
end
|
199
195
|
|
196
|
+
maxloop = 101
|
200
197
|
loop do
|
201
198
|
assert((maxloop-=1) > 0)
|
202
199
|
case c
|
@@ -220,7 +217,7 @@ class Unmangler::Borland
|
|
220
217
|
i = 0
|
221
218
|
|
222
219
|
begin # compute length
|
223
|
-
i = i
|
220
|
+
i = i*10 + c.to_i
|
224
221
|
c = advance()
|
225
222
|
end while isdigit(c)
|
226
223
|
|
@@ -252,9 +249,8 @@ class Unmangler::Borland
|
|
252
249
|
advance()
|
253
250
|
copy_type(@target, 0)
|
254
251
|
len = @target - name
|
255
|
-
len = MAXBUFFLEN - 1 if (len > MAXBUFFLEN - 1)
|
256
|
-
|
257
|
-
buff[len] = 0
|
252
|
+
#len = MAXBUFFLEN - 1 if (len > MAXBUFFLEN - 1)
|
253
|
+
buff = name[0,len]
|
258
254
|
@target = name
|
259
255
|
end
|
260
256
|
|
@@ -274,18 +270,17 @@ class Unmangler::Borland
|
|
274
270
|
|
275
271
|
when 'C' # C++ wide char
|
276
272
|
c = advance()
|
277
|
-
if
|
273
|
+
if c == 's'
|
278
274
|
tname = "char16_t"
|
279
|
-
elsif
|
275
|
+
elsif c == 'i'
|
280
276
|
tname = "char32_t"
|
281
277
|
else
|
282
|
-
raise "Unknown type"
|
278
|
+
raise "Unknown wide char type: 'C#{c}'"
|
283
279
|
end
|
284
280
|
|
285
281
|
when 'M','r','h','p' # member pointer, reference, rvalue reference, pointer
|
286
282
|
if (@savechar == 'M')
|
287
|
-
c = input() # [BTS-??????]
|
288
|
-
case c
|
283
|
+
case c = input() # [BTS-??????]
|
289
284
|
when 'x'; is_const = true; c = advance() # [BCB-272500]
|
290
285
|
when 'w'; is_volatile = true; c = advance()
|
291
286
|
end
|
@@ -315,7 +310,7 @@ class Unmangler::Borland
|
|
315
310
|
when 'h'; append('&&')
|
316
311
|
when 'p'; append(' *')
|
317
312
|
when 'M'
|
318
|
-
assert(buff
|
313
|
+
assert(buff)
|
319
314
|
copy_char(' ')
|
320
315
|
copy_string(buff)
|
321
316
|
append '::*'
|
@@ -363,7 +358,7 @@ class Unmangler::Borland
|
|
363
358
|
end
|
364
359
|
|
365
360
|
save_adjqual = @adjust_quals
|
366
|
-
@adjust_quals =
|
361
|
+
@adjust_quals = false
|
367
362
|
|
368
363
|
copy_char('(')
|
369
364
|
copy_args('$', 0)
|
@@ -403,7 +398,7 @@ class Unmangler::Borland
|
|
403
398
|
def copy_delphi4args(_end, tmplargs)
|
404
399
|
first = true
|
405
400
|
_begin = start = nil
|
406
|
-
termchar =
|
401
|
+
termchar = nil
|
407
402
|
|
408
403
|
tmplargs =
|
409
404
|
case tmplargs
|
@@ -438,11 +433,7 @@ class Unmangler::Borland
|
|
438
433
|
|
439
434
|
when 'i'
|
440
435
|
if _begin[0,5] == '4bool'
|
441
|
-
|
442
|
-
copy_string("false")
|
443
|
-
else
|
444
|
-
copy_string("true")
|
445
|
-
end
|
436
|
+
copy_string( input() == '0' ? "false" : "true" )
|
446
437
|
advance()
|
447
438
|
break
|
448
439
|
else
|
@@ -482,13 +473,16 @@ class Unmangler::Borland
|
|
482
473
|
end # while c && c != _end
|
483
474
|
end
|
484
475
|
|
485
|
-
|
476
|
+
# The mangler, when mangling argument types, will create
|
477
|
+
# backreferences if the type has already been seen. These take the
|
478
|
+
# form t?, where ? can be either 0-9, or a-z.
|
479
|
+
PEntry = Struct.new :start, :len
|
486
480
|
|
487
481
|
def copy_args(_end, tmplargs)
|
488
482
|
c = input()
|
489
483
|
first = true
|
490
484
|
_begin = start = nil
|
491
|
-
scanned =
|
485
|
+
scanned = false
|
492
486
|
param_table = []
|
493
487
|
|
494
488
|
tmplargs =
|
@@ -497,7 +491,7 @@ class Unmangler::Borland
|
|
497
491
|
else true
|
498
492
|
end
|
499
493
|
|
500
|
-
while
|
494
|
+
while c && ![0, "\0", _end].include?(c)
|
501
495
|
if first
|
502
496
|
first = false
|
503
497
|
else
|
@@ -507,42 +501,40 @@ class Unmangler::Borland
|
|
507
501
|
_begin = @source.dup
|
508
502
|
start = @target.dup
|
509
503
|
|
510
|
-
param_table << PEntry.new
|
511
|
-
|
512
|
-
|
513
|
-
scanned = 0
|
504
|
+
param_table << PEntry.new( @target.dup )
|
505
|
+
scanned = false
|
514
506
|
|
515
|
-
while
|
507
|
+
while c == 'x' || c == 'w'
|
516
508
|
# Decode 'const'/'volatile' modifiers [BCB-265738]
|
517
509
|
case c
|
518
510
|
when 'x'; copy_string("const ")
|
519
511
|
when 'w'; copy_string("volatile ")
|
520
512
|
end
|
521
|
-
scanned =
|
513
|
+
scanned = true
|
522
514
|
c = advance()
|
523
515
|
end
|
524
516
|
|
525
|
-
if
|
517
|
+
if scanned && c != 't'
|
526
518
|
@source = _begin.dup
|
527
519
|
end
|
528
520
|
|
529
|
-
if
|
530
|
-
copy_type(@target, ! tmplargs)
|
531
|
-
else
|
521
|
+
if c == 't'
|
532
522
|
c = advance()
|
533
|
-
ptindex = c.to_i(
|
534
|
-
assert(param_table[ptindex].
|
523
|
+
ptindex = c.to_i(36) - 1
|
524
|
+
assert(param_table[ptindex].start)
|
535
525
|
assert(param_table[ptindex].len > 0)
|
536
|
-
copy_string param_table[ptindex].
|
526
|
+
copy_string param_table[ptindex].start[0, param_table[ptindex].len]
|
537
527
|
advance()
|
528
|
+
else
|
529
|
+
copy_type(@target, ! tmplargs)
|
538
530
|
end
|
539
531
|
|
540
|
-
param_table.last.len = @target - param_table.last.
|
532
|
+
param_table.last.len = @target - param_table.last.start
|
541
533
|
|
542
534
|
c = input()
|
543
535
|
|
544
536
|
if (tmplargs && c == '$') # non-type template argument
|
545
|
-
termchar =
|
537
|
+
termchar = nil
|
546
538
|
@target = start.dup
|
547
539
|
c = advance()
|
548
540
|
advance()
|
@@ -555,11 +547,7 @@ class Unmangler::Borland
|
|
555
547
|
|
556
548
|
when 'i'
|
557
549
|
if _begin[0,5] == "4bool"
|
558
|
-
|
559
|
-
copy_string("false")
|
560
|
-
else
|
561
|
-
copy_string("true")
|
562
|
-
end
|
550
|
+
copy_string( input() == '0' ? "false" : "true" )
|
563
551
|
advance()
|
564
552
|
break
|
565
553
|
end
|
@@ -567,7 +555,7 @@ class Unmangler::Borland
|
|
567
555
|
|
568
556
|
when 'j','g','e'
|
569
557
|
copy_until('$')
|
570
|
-
copy_char(termchar) if
|
558
|
+
copy_char(termchar) if termchar
|
571
559
|
break
|
572
560
|
|
573
561
|
when 'm'
|
@@ -615,7 +603,7 @@ class Unmangler::Borland
|
|
615
603
|
# name from a template argument, for example.
|
616
604
|
|
617
605
|
save_setqual = @set_qual
|
618
|
-
@set_qual =
|
606
|
+
@set_qual = false
|
619
607
|
|
620
608
|
if isDelphi4name
|
621
609
|
copy_delphi4args(TMPLCODE, 1)
|
@@ -633,27 +621,16 @@ class Unmangler::Borland
|
|
633
621
|
advance()
|
634
622
|
end
|
635
623
|
|
636
|
-
def isdigit c
|
637
|
-
c =~ /\A\d\Z/
|
638
|
-
end
|
639
|
-
|
640
|
-
def assert cond
|
641
|
-
unless cond
|
642
|
-
# puts
|
643
|
-
# puts
|
644
|
-
# p @source
|
645
|
-
# p @source[0..-1]
|
646
|
-
# puts
|
647
|
-
# p @target
|
648
|
-
# puts
|
649
|
-
raise
|
650
|
-
end
|
651
|
-
end
|
652
|
-
|
653
624
|
def copy_name tmplname
|
654
625
|
start = save_setqual = nil
|
655
626
|
c = input()
|
656
627
|
|
628
|
+
tmplname =
|
629
|
+
case tmplname
|
630
|
+
when 0, nil, false; false
|
631
|
+
else true
|
632
|
+
end
|
633
|
+
|
657
634
|
# Start outputting the qualifier names and the base name.
|
658
635
|
|
659
636
|
while true
|
@@ -715,7 +692,7 @@ class Unmangler::Borland
|
|
715
692
|
end
|
716
693
|
|
717
694
|
when ARGLIST # special name, or arglist
|
718
|
-
return
|
695
|
+
return if tmplname
|
719
696
|
|
720
697
|
c = advance()
|
721
698
|
if c == 'x'
|
@@ -766,7 +743,7 @@ class Unmangler::Borland
|
|
766
743
|
advance()
|
767
744
|
copy_string("operator ")
|
768
745
|
save_setqual = @set_qual
|
769
|
-
@set_qual =
|
746
|
+
@set_qual = false
|
770
747
|
copy_type(@target, 0)
|
771
748
|
@set_qual = save_setqual
|
772
749
|
assert(input() == ARGLIST)
|
@@ -902,8 +879,13 @@ class Unmangler::Borland
|
|
902
879
|
# will be unmangled, and not the arguments.
|
903
880
|
|
904
881
|
def unmangle src, args = {}
|
882
|
+
# all Borland mangled names start with '@' character.
|
905
883
|
return src if !src || src.empty? || src[0] != '@'
|
906
884
|
|
885
|
+
# check for Microsoft compatible fastcall names, which are of the form:
|
886
|
+
# @funcName@<one or more digits indicating size of all parameters>
|
887
|
+
return src if src =~ /\A@.*@\d+\Z/
|
888
|
+
|
907
889
|
# unmangle args? defaulting to true
|
908
890
|
doArgs = args.fetch(:args, true)
|
909
891
|
|
@@ -927,19 +909,16 @@ class Unmangler::Borland
|
|
927
909
|
|
928
910
|
@savechar = 0
|
929
911
|
|
930
|
-
# All mangled names start with '@' character.
|
931
|
-
|
932
912
|
src = src[1..-1] # skip initial '@'
|
933
913
|
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
end
|
914
|
+
# ZZZ XXX not sure if it's needed now
|
915
|
+
# if src[/[a-z]/]
|
916
|
+
# # contains lowercase letters => not Pascal
|
917
|
+
# # b/c Pascal names can not contain lowercase letters
|
918
|
+
# else
|
919
|
+
# # Pascal, convert uppercase Pascal names to lowercase
|
920
|
+
# src.downcase!
|
921
|
+
# end
|
943
922
|
|
944
923
|
# This is at LEAST a member name, if not a fully mangled template
|
945
924
|
# or function name. So, begin outputting the subnames. We set up
|
@@ -950,14 +929,14 @@ class Unmangler::Borland
|
|
950
929
|
@source_string = src
|
951
930
|
@source = StringPtr.new(@source_string)
|
952
931
|
@prevqual = @qualend = @base_name = @base_end = nil
|
953
|
-
@set_qual =
|
932
|
+
@set_qual = true
|
954
933
|
|
955
934
|
# Start outputting the qualifier names and the base name.
|
956
935
|
|
957
936
|
@namebase = @target.dup
|
958
937
|
|
959
938
|
copy_name(0)
|
960
|
-
@set_qual =
|
939
|
+
@set_qual = false
|
961
940
|
@base_end = @target.dup
|
962
941
|
|
963
942
|
if (@kind & UM_KINDMASK) == UM_TPDSC || (@kind & UM_SPECMASK) != 0
|
@@ -966,25 +945,17 @@ class Unmangler::Borland
|
|
966
945
|
@namebase = p + 1
|
967
946
|
end
|
968
947
|
|
969
|
-
if (@kind & UM_KINDMASK
|
970
|
-
|
971
|
-
|
972
|
-
if (@kind & UM_KINDMASK) == UM_DESTRUCTOR
|
973
|
-
copy_char('~')
|
974
|
-
end
|
948
|
+
if [UM_CONSTRUCTOR,UM_DESTRUCTOR].include?( @kind & UM_KINDMASK )
|
949
|
+
copy_char('~') if @kind & UM_KINDMASK == UM_DESTRUCTOR
|
975
950
|
|
976
|
-
if
|
951
|
+
if @qualend
|
952
|
+
start = @prevqual ? (@prevqual+2) : @namebase.dup
|
953
|
+
len = @qualend - start
|
954
|
+
copy_string(start, len)
|
955
|
+
else
|
977
956
|
# It's a bcc-created static constructor??
|
978
957
|
# give it a name.
|
979
958
|
copy_string("unknown")
|
980
|
-
else
|
981
|
-
if !@prevqual
|
982
|
-
start = @namebase.dup
|
983
|
-
else
|
984
|
-
start = @prevqual + 2
|
985
|
-
end
|
986
|
-
len = @qualend - start
|
987
|
-
copy_string(start, len)
|
988
959
|
end
|
989
960
|
end
|
990
961
|
|
@@ -998,8 +969,8 @@ class Unmangler::Borland
|
|
998
969
|
# Output the function parameters, and return type in the case
|
999
970
|
# of template function specializations.
|
1000
971
|
|
1001
|
-
@set_qual =
|
1002
|
-
@adjust_quals =
|
972
|
+
@set_qual = false
|
973
|
+
@adjust_quals = true
|
1003
974
|
|
1004
975
|
copy_type(@namebase, 0)
|
1005
976
|
|
@@ -1019,6 +990,9 @@ class Unmangler::Borland
|
|
1019
990
|
@kind |= UM_QUALIFIED
|
1020
991
|
end
|
1021
992
|
|
993
|
+
# trim unwanted result tail, if any
|
994
|
+
@target[0..-1] = ''
|
995
|
+
|
1022
996
|
# If the user wanted the qualifier and base name saved, then do it now.
|
1023
997
|
|
1024
998
|
# TODO
|
@@ -1050,37 +1024,29 @@ class Unmangler::Borland
|
|
1050
1024
|
@result.sub! /\A__tpdsc__ /,''
|
1051
1025
|
end
|
1052
1026
|
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
# if can not unmangle
|
1058
|
-
def safe_unmangle name, *args
|
1059
|
-
unmangle name, *args
|
1060
|
-
rescue
|
1061
|
-
name
|
1062
|
-
end
|
1027
|
+
# copy IDA syntax for class ctor/dtor:
|
1028
|
+
# was: Classes::TThread::operator `class destructor`()
|
1029
|
+
# now: Classes::TThread::`class destructor`()
|
1030
|
+
@result.sub! '::operator `class', '::`class'
|
1063
1031
|
|
1064
|
-
|
1065
|
-
new.unmangle(*args)
|
1032
|
+
@result
|
1066
1033
|
end
|
1067
1034
|
|
1068
|
-
def self.safe_unmangle *args
|
1069
|
-
new.safe_unmangle(*args)
|
1070
|
-
end
|
1071
1035
|
end # class Unmangler
|
1072
1036
|
|
1073
1037
|
###################################################################
|
1074
1038
|
|
1075
1039
|
if $0 == __FILE__
|
1040
|
+
$:.unshift("./lib")
|
1041
|
+
require 'unmangler/string_ptr'
|
1076
1042
|
require 'awesome_print'
|
1077
1043
|
require 'pp'
|
1078
1044
|
|
1079
|
-
def check src, want,
|
1045
|
+
def check src, want, args = {}
|
1080
1046
|
u = Unmangler::Borland.new
|
1081
1047
|
got = nil
|
1082
1048
|
begin
|
1083
|
-
got = u.unmangle(src,
|
1049
|
+
got = u.unmangle(src, args)
|
1084
1050
|
rescue
|
1085
1051
|
pp u
|
1086
1052
|
raise
|
@@ -1088,14 +1054,21 @@ if $0 == __FILE__
|
|
1088
1054
|
if got == want
|
1089
1055
|
print ".".green
|
1090
1056
|
else
|
1091
|
-
puts "[!] want: #{want.inspect}"
|
1092
|
-
puts "[!] got: #{got.inspect}"
|
1093
|
-
pp u
|
1094
1057
|
puts
|
1058
|
+
puts "[!] src: #{src.inspect.gray}"
|
1059
|
+
puts "[!] want: #{want.inspect.yellow}"
|
1060
|
+
puts "[!] got: #{got.inspect.red}"
|
1061
|
+
puts
|
1062
|
+
pp u
|
1095
1063
|
exit 1
|
1096
1064
|
end
|
1097
1065
|
end
|
1098
1066
|
|
1067
|
+
if ARGV.any?
|
1068
|
+
check ARGV[0], ARGV[1]
|
1069
|
+
exit
|
1070
|
+
end
|
1071
|
+
|
1099
1072
|
check "@afunc$qxzcupi", "afunc(const signed char, int *)"
|
1100
1073
|
check "@foo$qpqfi$d", "foo(double (*)(float, int))"
|
1101
1074
|
check "@myclass@func$qil","myclass::func(int, long)"
|
@@ -1133,8 +1106,16 @@ if $0 == __FILE__
|
|
1133
1106
|
check "@Dbcommon@GetTableNameFromSQLEx$qqrx17System@WideString25Dbcommon@IDENTIFIEROption",
|
1134
1107
|
"__fastcall Dbcommon::GetTableNameFromSQLEx(const System::WideString, Dbcommon::IDENTIFIEROption)"
|
1135
1108
|
|
1136
|
-
|
1137
|
-
|
1109
|
+
check "@$xt$p27System@%AnsiStringT$us$i0$%", "__tpdsc__ System::AnsiStringT<0> *"
|
1110
|
+
|
1111
|
+
check "@Adomcore_4_3@TDomNamedNodeMap@$bctr$qqrpx21Adomcore_4_3@TDomNodepx13Classes@TListx54System@%Set$t25Adomcore_4_3@TDomNodeType$iuc$0$iuc$11%xo",
|
1112
|
+
"__fastcall Adomcore_4_3::TDomNamedNodeMap::TDomNamedNodeMap(Adomcore_4_3::TDomNode *, Classes::TList *, const System::Set<Adomcore_4_3::TDomNodeType, 0, 11>, const bool)"
|
1113
|
+
|
1114
|
+
check '@ATL@%CComObjectRootEx$25ATL@CComSingleThreadModel%@$bctr$qv',
|
1115
|
+
"ATL::CComObjectRootEx<ATL::CComSingleThreadModel>::CComObjectRootEx<ATL::CComSingleThreadModel>()"
|
1116
|
+
|
1117
|
+
check '@Classes@TThread@$bcdtr$qqrv', '__fastcall Classes::TThread::`class destructor`()'
|
1118
|
+
check '@Timespan@TTimeSpan@$bcctr$qqrv', '__fastcall Timespan::TTimeSpan::`class constructor`()'
|
1138
1119
|
|
1139
1120
|
####################################
|
1140
1121
|
# w/o args
|
@@ -1142,11 +1123,11 @@ if $0 == __FILE__
|
|
1142
1123
|
|
1143
1124
|
check "@Dbcommon@GetTableNameFromSQLEx$qqrx17System@WideString25Dbcommon@IDENTIFIEROption",
|
1144
1125
|
"Dbcommon::GetTableNameFromSQLEx",
|
1145
|
-
false
|
1126
|
+
:args => false
|
1146
1127
|
|
1147
1128
|
check "@std@%vector$51boost@archive@detail@basic_iarchive_impl@cobject_id69std@%allocator$51boost@archive@detail@basic_iarchive_impl@cobject_id%%@$bsubs$qui",
|
1148
1129
|
"std::vector<boost::archive::detail::basic_iarchive_impl::cobject_id, std::allocator<boost::archive::detail::basic_iarchive_impl::cobject_id> >::operator []",
|
1149
|
-
false
|
1130
|
+
:args => false
|
1150
1131
|
|
1151
1132
|
puts
|
1152
1133
|
end
|