Skip to content

Commit dc93d09

Browse files
authored
Merge pull request #5 from phith0n/feature/walker
added walker for the Objects
2 parents 1a13df7 + 99a83be commit dc93d09

22 files changed

+427
-17
lines changed

example/main.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
package main
22

33
import (
4-
"encoding/hex"
54
"fmt"
5+
"github.com/phith0n/zkar/serz"
6+
"io/ioutil"
7+
"log"
68
)
79

810
func main() {
9-
var s = "\x8c\xA3\x8B"
10-
var bs = []byte(s)
11-
fmt.Println(bs, s, hex.EncodeToString(bs))
11+
data, _ := ioutil.ReadFile("./testcases/ysoserial/Jdk7u21.ser")
12+
serialization, err := serz.FromBytes(data)
13+
if err != nil {
14+
log.Fatal("parse error")
15+
}
16+
17+
desc := serz.FindClassDesc(serialization, "sun.reflect.annotation.AnnotationInvocationHandler")
18+
if desc != nil {
19+
fmt.Println(desc.ToString())
20+
} else {
21+
log.Fatal("class desc not found")
22+
}
1223
}

serz/parser.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
type Object interface {
1111
ToBytes() []byte
1212
ToString() string
13+
AllowWalked
1314
}
1415

1516
type Serialization struct {
@@ -91,3 +92,17 @@ func (ois *Serialization) ToJDK8u20Bytes() []byte {
9192
1,
9293
)
9394
}
95+
96+
func (ois *Serialization) Walk(callback WalkCallback) error {
97+
for _, content := range ois.Contents {
98+
if err := callback(content); err != nil {
99+
return err
100+
}
101+
102+
if err := content.Walk(callback); err != nil {
103+
return err
104+
}
105+
}
106+
107+
return nil
108+
}

serz/parser_test.go

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,14 @@ func extractPackage(name string) string {
2828
}
2929

3030
func TestYsoserial(t *testing.T) {
31-
files, err := filepath.Glob("../testcases/ysoserial/*.ser")
32-
require.Nil(t, err)
33-
require.NotZero(t, len(files))
34-
35-
for _, name := range files {
36-
data, err := ioutil.ReadFile(name)
37-
require.Nil(t, err)
38-
39-
ser, err := FromBytes(data)
40-
require.Nilf(t, err, "an error is occurred in file %v", name)
41-
require.Truef(t, bytes.Equal(data, ser.ToBytes()), "original serz data is different from generation data in file %v", name)
42-
}
31+
walkAndTest("../testcases/ysoserial/*.ser", t, func(filename string, data []byte, ser *Serialization) {
32+
require.Truef(
33+
t,
34+
bytes.Equal(data, ser.ToBytes()),
35+
"original data is different from generation data in file %v",
36+
filename,
37+
)
38+
})
4339
}
4440

4541
func TestJDK8u20(t *testing.T) {
@@ -49,7 +45,7 @@ func TestJDK8u20(t *testing.T) {
4945

5046
ser, err := FromJDK8u20Bytes(data)
5147
require.Nilf(t, err, "an error is occurred in file %v", filename)
52-
require.Truef(t, bytes.Equal(data, ser.ToJDK8u20Bytes()), "original serz data is different from generation data in file %v", filename)
48+
require.Truef(t, bytes.Equal(data, ser.ToJDK8u20Bytes()), "original data is different from generation data in file %v", filename)
5349
}
5450

5551
func TestMain(m *testing.M) {
@@ -113,3 +109,19 @@ func TestMain(m *testing.M) {
113109
cleanup:
114110
os.Exit(exitCode)
115111
}
112+
113+
func walkAndTest(pathGlob string, t *testing.T, callback func(filename string, data []byte, ser *Serialization)) {
114+
files, err := filepath.Glob(pathGlob)
115+
require.Nil(t, err)
116+
require.NotZero(t, len(files))
117+
118+
for _, name := range files {
119+
data, err := ioutil.ReadFile(name)
120+
require.Nil(t, err)
121+
122+
ser, err := FromBytes(data)
123+
require.Nilf(t, err, "an error is occurred in file %v", name)
124+
125+
callback(name, data, ser)
126+
}
127+
}

serz/tc_array.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,28 @@ func (t *TCArray) ToString() string {
5858
return b.String()
5959
}
6060

61+
func (t *TCArray) Walk(callback WalkCallback) error {
62+
if err := callback(t.ClassPointer); err != nil {
63+
return err
64+
}
65+
66+
if err := t.ClassPointer.Walk(callback); err != nil {
67+
return err
68+
}
69+
70+
for _, v := range t.ArrayData {
71+
if err := callback(v); err != nil {
72+
return err
73+
}
74+
75+
if err := v.Walk(callback); err != nil {
76+
return err
77+
}
78+
}
79+
80+
return nil
81+
}
82+
6183
func (t *TCArray) DumpByteArray() string {
6284
var builder = &strings.Builder{}
6385
var dumper = hex.Dumper(builder)

serz/tc_blockdata.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ func (bd *TCBlockData) ToString() string {
3535
return b.String()
3636
}
3737

38+
func (bd *TCBlockData) Walk(callback WalkCallback) error {
39+
return nil
40+
}
41+
3842
func readTCBlockData(stream *ObjectStream) (*TCBlockData, error) {
3943
// read JAVA_TC_BLOCKDATA or JAVA_TC_BLOCKDATALONG Flag
4044
flag, _ := stream.ReadN(1)

serz/tc_class.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ func (c *TCClass) ToString() string {
2222
return b.String()
2323
}
2424

25+
func (c *TCClass) Walk(callback WalkCallback) error {
26+
if err := callback(c.ClassPointer); err != nil {
27+
return err
28+
}
29+
30+
return c.ClassPointer.Walk(callback)
31+
}
32+
2533
func readTCClass(stream *ObjectStream) (*TCClass, error) {
2634
var class = new(TCClass)
2735
var err error

serz/tc_classdata.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,34 @@ func (cd *TCClassData) ToString() string {
6262
return b.String()
6363
}
6464

65+
func (cd *TCClassData) Walk(callback WalkCallback) error {
66+
for _, data := range cd.FieldDatas {
67+
if err := callback(data); err != nil {
68+
return err
69+
}
70+
71+
if err := data.Walk(callback); err != nil {
72+
return err
73+
}
74+
}
75+
76+
if !cd.HasAnnotation {
77+
return nil
78+
}
79+
80+
for _, anno := range cd.ObjectAnnotation {
81+
if err := callback(anno); err != nil {
82+
return err
83+
}
84+
85+
if err := anno.Walk(callback); err != nil {
86+
return err
87+
}
88+
}
89+
90+
return nil
91+
}
92+
6593
func readTCClassData(stream *ObjectStream, desc *TCClassDesc) (*TCClassData, error) {
6694
var err error
6795
var classData = &TCClassData{

serz/tc_classpointer.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,28 @@ func (cp *TCClassPointer) ToString() string {
4848
return result
4949
}
5050

51+
func (cp *TCClassPointer) Walk(callback WalkCallback) error {
52+
var obj Object
53+
switch cp.Flag {
54+
case JAVA_TC_NULL:
55+
obj = cp.Null
56+
case JAVA_TC_REFERENCE:
57+
obj = cp.Reference
58+
case JAVA_TC_CLASSDESC:
59+
obj = cp.NormalClassDesc
60+
case JAVA_TC_PROXYCLASSDESC:
61+
obj = cp.ProxyClassDesc
62+
default:
63+
panic("unexpected TCClassPointer Flag")
64+
}
65+
66+
if err := callback(obj); err != nil {
67+
return err
68+
}
69+
70+
return obj.Walk(callback)
71+
}
72+
5173
func (cp *TCClassPointer) FindClassBag(stream *ObjectStream) (*ClassBag, error) {
5274
var normalClassDesc *TCClassDesc
5375
var proxyClassDesc *TCProxyClassDesc

serz/tc_content.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,34 @@ func (c *TCContent) ToString() string {
6868
return bs
6969
}
7070

71+
func (c *TCContent) Walk(callback WalkCallback) error {
72+
var obj Object
73+
switch c.Flag {
74+
case JAVA_TC_STRING, JAVA_TC_LONGSTRING:
75+
obj = c.String
76+
case JAVA_TC_BLOCKDATA, JAVA_TC_BLOCKDATALONG:
77+
obj = c.BlockData
78+
case JAVA_TC_CLASS:
79+
obj = c.Class
80+
case JAVA_TC_OBJECT:
81+
obj = c.Object
82+
case JAVA_TC_NULL:
83+
obj = c.Null
84+
case JAVA_TC_REFERENCE:
85+
obj = c.Reference
86+
case JAVA_TC_ENUM:
87+
obj = c.Enum
88+
case JAVA_TC_ARRAY:
89+
obj = c.Array
90+
}
91+
92+
if err := callback(obj); err != nil {
93+
return err
94+
}
95+
96+
return obj.Walk(callback)
97+
}
98+
7199
func readTCContent(stream *ObjectStream) (*TCContent, error) {
72100
var err error = nil
73101
var content = new(TCContent)

serz/tc_enum.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,22 @@ func (e *TCEnum) ToString() string {
2525
return b.String()
2626
}
2727

28+
func (e *TCEnum) Walk(callback WalkCallback) error {
29+
if err := callback(e.ClassPointer); err != nil {
30+
return err
31+
}
32+
33+
if err := e.ClassPointer.Walk(callback); err != nil {
34+
return err
35+
}
36+
37+
if err := callback(e.ConstantName); err != nil {
38+
return err
39+
}
40+
41+
return e.ConstantName.Walk(callback)
42+
}
43+
2844
func readTCEnum(stream *ObjectStream) (*TCEnum, error) {
2945
var enum = new(TCEnum)
3046
var err error

serz/tc_fielddesc.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,26 @@ func (f *TCFieldDesc) ToString() string {
5454
return b.String()
5555
}
5656

57+
func (f *TCFieldDesc) Walk(callback WalkCallback) error {
58+
if err := callback(f.FieldName); err != nil {
59+
return err
60+
}
61+
62+
if err := f.FieldName.Walk(callback); err != nil {
63+
return err
64+
}
65+
66+
if f.TypeCode == "L" || f.TypeCode == "[" {
67+
if err := callback(f.ClassName); err != nil {
68+
return err
69+
}
70+
71+
return f.ClassName.Walk(callback)
72+
}
73+
74+
return nil
75+
}
76+
5777
func readTCField(stream *ObjectStream) (*TCFieldDesc, error) {
5878
var fieldDesc = new(TCFieldDesc)
5979
typeCode, err := stream.ReadN(1)

serz/tc_normalclassdesc.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,42 @@ func (desc *TCClassDesc) ToString() string {
7474
return b.String()
7575
}
7676

77+
func (desc *TCClassDesc) Walk(callback WalkCallback) error {
78+
if err := callback(desc.ClassName); err != nil {
79+
return err
80+
}
81+
82+
if err := desc.ClassName.Walk(callback); err != nil {
83+
return err
84+
}
85+
86+
for _, field := range desc.Fields {
87+
if err := callback(field); err != nil {
88+
return err
89+
}
90+
91+
if err := field.Walk(callback); err != nil {
92+
return err
93+
}
94+
}
95+
96+
for _, anno := range desc.ClassAnnotation {
97+
if err := callback(anno); err != nil {
98+
return err
99+
}
100+
101+
if err := anno.Walk(callback); err != nil {
102+
return err
103+
}
104+
}
105+
106+
if err := callback(desc.SuperClassPointer); err != nil {
107+
return err
108+
}
109+
110+
return desc.SuperClassPointer.Walk(callback)
111+
}
112+
77113
// HasFlag Check if a TCClassDesc object has a flag
78114
func (desc *TCClassDesc) HasFlag(flag byte) bool {
79115
return (desc.ClassDescFlags & flag) == flag

serz/tc_null.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ func (n *TCNull) ToString() string {
1616
return b.String()
1717
}
1818

19+
func (n *TCNull) Walk(callback WalkCallback) error {
20+
return nil
21+
}
22+
1923
func readTCNull(stream *ObjectStream) *TCNull {
2024
_, _ = stream.ReadN(1)
2125
return new(TCNull)

serz/tc_object.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,28 @@ func (oo *TCObject) ToString() string {
3333
return b.String()
3434
}
3535

36+
func (oo *TCObject) Walk(callback WalkCallback) error {
37+
if err := callback(oo.ClassPointer); err != nil {
38+
return err
39+
}
40+
41+
if err := oo.ClassPointer.Walk(callback); err != nil {
42+
return err
43+
}
44+
45+
for _, data := range oo.ClassDatas {
46+
if err := callback(data); err != nil {
47+
return err
48+
}
49+
50+
if err := data.Walk(callback); err != nil {
51+
return err
52+
}
53+
}
54+
55+
return nil
56+
}
57+
3658
func readTCObject(stream *ObjectStream) (*TCObject, error) {
3759
var obj = new(TCObject)
3860
var err error

0 commit comments

Comments
 (0)