unmangler 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|