1
- // +build !windows,cgo
2
-
3
1
/*
4
2
Copyright © 2019 blacktop
5
3
@@ -24,17 +22,19 @@ THE SOFTWARE.
24
22
package cmd
25
23
26
24
import (
25
+ "bytes"
27
26
"fmt"
28
27
"sort"
29
28
"strconv"
30
29
"strings"
31
30
32
31
"github.com/apex/log"
32
+ "github.com/blacktop/go-arm64"
33
33
"github.com/blacktop/go-macho"
34
34
"github.com/blacktop/ipsw/internal/demangle"
35
- "github.com/knightsc/gapstone"
36
35
"github.com/pkg/errors"
37
36
"github.com/spf13/cobra"
37
+ // "github.com/knightsc/gapstone"
38
38
)
39
39
40
40
var (
@@ -89,6 +89,13 @@ func isFunctionStart(starts []uint64, addr uint64) uint64 {
89
89
return 0
90
90
}
91
91
92
+ func pad (length int ) string {
93
+ if length > 0 {
94
+ return strings .Repeat (" " , length )
95
+ }
96
+ return " "
97
+ }
98
+
92
99
// disCmd represents the dis command
93
100
var disCmd = & cobra.Command {
94
101
Use : "disass" ,
@@ -135,117 +142,193 @@ var disCmd = &cobra.Command{
135
142
136
143
found := false
137
144
for _ , sec := range m .Sections {
138
- if sec .Name == "__text" {
139
- if sec .Addr <= startAddr && startAddr < (sec .Addr + sec .Size ) {
140
- found = true
145
+ // if sec.Name == "__text" {
146
+ if sec .Addr <= startAddr && startAddr < (sec .Addr + sec .Size ) {
147
+ found = true
141
148
142
- memOffset := startAddr - sec .Addr
143
- if instructions * 4 > sec .Size - memOffset {
144
- data = make ([]byte , sec .Size - memOffset )
145
- }
146
-
147
- _ , err := sec .ReadAt (data , int64 (memOffset ))
148
- if err != nil {
149
- return err
150
- }
149
+ memOffset := startAddr - sec .Addr
150
+ if instructions * 4 > sec .Size - memOffset {
151
+ data = make ([]byte , sec .Size - memOffset )
152
+ }
151
153
152
- break
154
+ _ , err := sec .ReadAt (data , int64 (memOffset ))
155
+ if err != nil {
156
+ return err
153
157
}
158
+
159
+ break
154
160
}
161
+ // }
155
162
}
156
163
157
164
if ! found {
158
165
return fmt .Errorf ("supplied vaddr not found in any __text section" )
159
166
}
160
167
161
- engine , err := gapstone .New (
162
- gapstone .CS_ARCH_ARM64 ,
163
- gapstone .CS_MODE_ARM ,
164
- )
165
- if err != nil {
166
- return errors .Wrapf (err , "failed to create capstone engine" )
167
- }
168
-
169
- // turn on instruction details
170
- engine .SetOption (gapstone .CS_OPT_DETAIL , gapstone .CS_OPT_ON )
171
-
172
- insns , err := engine .Disasm (
173
- data ,
174
- startAddr ,
175
- 0 , // insns to disassemble, 0 for all
176
- )
177
- if err != nil {
178
- return errors .Wrapf (err , "failed to disassemble data" )
179
- }
180
-
181
- for i , insn := range insns {
168
+ for i := range arm64 .Disassemble (bytes .NewReader (data ), arm64.Options {StartAddress : int64 (startAddr )}) {
182
169
// check for start of a new function
183
- if funcStarts != nil && isFunctionStart (funcStarts , uint64 ( insn . Address )) != 0 {
184
- syms , err := m .FindAddressSymbols (uint64 ( insn . Address ))
170
+ if funcStarts != nil && isFunctionStart (funcStarts , i . Instruction . Address ( )) != 0 {
171
+ syms , err := m .FindAddressSymbols (i . Instruction . Address ( ))
185
172
if len (syms ) > 1 {
186
- log .Warnf ("found more than one symbol at address 0x%x, %v" , insn . Address , syms )
173
+ log .Warnf ("found more than one symbol at address 0x%x, %v" , i . Instruction . Address () , syms )
187
174
}
188
175
if err == nil {
189
176
var symName string
190
177
if demangleFlag {
191
178
symName = doDemangle (syms [0 ].Name )
192
- }
193
- fmt .Printf ("\n %s:\n " , symName )
194
- }
195
- }
196
-
197
- // lookup adrp/ldr or add address as a cstring or symbol name
198
- if Verbose && (insn .Mnemonic == "ldr" || insn .Mnemonic == "add" ) && insns [i - 1 ].Mnemonic == "adrp" {
199
- if insn .Arm64 .Operands != nil && len (insn .Arm64 .Operands ) > 1 {
200
- if insns [i - 1 ].Arm64 .Operands != nil && len (insns [i - 1 ].Arm64 .Operands ) > 1 {
201
- adrpRegister := insns [i - 1 ].Arm64 .Operands [0 ].Reg
202
- adrpImm := insns [i - 1 ].Arm64 .Operands [1 ].Imm
203
- if insn .Mnemonic == "ldr" && adrpRegister == insn .Arm64 .Operands [1 ].Mem .Base {
204
- adrpImm += int64 (insn .Arm64 .Operands [1 ].Mem .Disp )
205
- } else if insn .Mnemonic == "add" && adrpRegister == insn .Arm64 .Operands [0 ].Reg {
206
- adrpImm += insn .Arm64 .Operands [2 ].Imm
207
- }
208
- // markup disassemble with label comment
209
- syms , err := m .FindAddressSymbols (uint64 (adrpImm ))
210
- if len (syms ) > 1 {
211
- log .Warnf ("found more than one symbol at address 0x%x, %v" , uint64 (adrpImm ), syms )
212
- }
213
- if err == nil {
214
- var symName string
215
- if demangleFlag {
216
- symName = doDemangle (syms [0 ].Name )
217
- }
218
- insn .OpStr += fmt .Sprintf (" // %s" , symName )
219
- } else {
220
- cstr , err := m .GetCString (uint64 (adrpImm ))
221
- if err == nil {
222
- insn .OpStr += fmt .Sprintf (" // %s" , cstr )
179
+ } else {
180
+ for _ , sym := range syms {
181
+ if len (sym .Name ) > 0 {
182
+ symName = sym .Name
223
183
}
224
184
}
225
185
}
186
+ fmt .Printf ("\n %s:\n " , symName )
187
+ } else {
188
+ fmt .Printf ("\n func_%x:\n " , i .Instruction .Address ())
226
189
}
227
190
}
228
191
229
- // check if branch location is a function
230
- if strings .HasPrefix (insn .Mnemonic , "b" ) && strings .HasPrefix (insn .OpStr , "#0x" ) {
231
- if insn .Arm64 .Operands != nil && len (insn .Arm64 .Operands ) > 0 {
232
- syms , err := m .FindAddressSymbols (uint64 (insn .Arm64 .Operands [0 ].Imm ))
233
- if len (syms ) > 1 {
234
- log .Warnf ("found more than one symbol at address 0x%x, %v" , uint64 (insn .Arm64 .Operands [0 ].Imm ), syms )
235
- }
236
- if err == nil {
237
- var symName string
238
- if demangleFlag {
239
- symName = doDemangle (syms [0 ].Name )
240
- }
241
- insn .OpStr = symName
242
- }
243
- }
244
- }
245
-
246
- fmt .Printf ("0x%x:\t %s\t \t %s\n " , insn .Address , insn .Mnemonic , insn .OpStr )
192
+ // lookup adrp/ldr or add address as a cstring or symbol name
193
+ // if Verbose && (insn.Mnemonic == "ldr" || insn.Mnemonic == "add") && insns[i-1].Mnemonic == "adrp" {
194
+ // if insn.Arm64.Operands != nil && len(insn.Arm64.Operands) > 1 {
195
+ // if insns[i-1].Arm64.Operands != nil && len(insns[i-1].Arm64.Operands) > 1 {
196
+ // adrpRegister := insns[i-1].Arm64.Operands[0].Reg
197
+ // adrpImm := insns[i-1].Arm64.Operands[1].Imm
198
+ // if insn.Mnemonic == "ldr" && adrpRegister == insn.Arm64.Operands[1].Mem.Base {
199
+ // adrpImm += int64(insn.Arm64.Operands[1].Mem.Disp)
200
+ // } else if insn.Mnemonic == "add" && adrpRegister == insn.Arm64.Operands[0].Reg {
201
+ // adrpImm += insn.Arm64.Operands[2].Imm
202
+ // }
203
+ // // markup disassemble with label comment
204
+ // syms, err := m.FindAddressSymbols(uint64(adrpImm))
205
+ // if len(syms) > 1 {
206
+ // log.Warnf("found more than one symbol at address 0x%x, %v", uint64(adrpImm), syms)
207
+ // }
208
+ // if err == nil {
209
+ // var symName string
210
+ // if demangleFlag {
211
+ // symName = doDemangle(syms[0].Name)
212
+ // }
213
+ // insn.OpStr += fmt.Sprintf(" // %s", symName)
214
+ // } else {
215
+ // cstr, err := m.GetCString(uint64(adrpImm))
216
+ // if err == nil {
217
+ // insn.OpStr += fmt.Sprintf(" // %s", cstr)
218
+ // }
219
+ // }
220
+ // }
221
+ // }
222
+ // }
223
+
224
+ // // check if branch location is a function
225
+ // if strings.HasPrefix(insn.Mnemonic, "b") && strings.HasPrefix(insn.OpStr, "#0x") {
226
+ // if insn.Arm64.Operands != nil && len(insn.Arm64.Operands) > 0 {
227
+ // syms, err := m.FindAddressSymbols(uint64(insn.Arm64.Operands[0].Imm))
228
+ // if len(syms) > 1 {
229
+ // log.Warnf("found more than one symbol at address 0x%x, %v", uint64(insn.Arm64.Operands[0].Imm), syms)
230
+ // }
231
+ // if err == nil {
232
+ // var symName string
233
+ // if demangleFlag {
234
+ // symName = doDemangle(syms[0].Name)
235
+ // }
236
+ // insn.OpStr = symName
237
+ // }
238
+ // }
239
+ // }
240
+ fmt .Printf ("%#08x: %s\t %s%s%s\n " , i .Instruction .Address (), i .Instruction .OpCodes (), i .Instruction .Operation (), pad (10 - len (i .Instruction .Operation ().String ())), i .Instruction .OpStr ())
247
241
}
248
242
243
+ // fmt.Println("CAPSTONE====================================================")
244
+ // engine, err := gapstone.New(
245
+ // gapstone.CS_ARCH_ARM64,
246
+ // gapstone.CS_MODE_ARM,
247
+ // )
248
+ // if err != nil {
249
+ // return errors.Wrapf(err, "failed to create capstone engine")
250
+ // }
251
+
252
+ // // turn on instruction details
253
+ // engine.SetOption(gapstone.CS_OPT_DETAIL, gapstone.CS_OPT_ON)
254
+
255
+ // insns, err := engine.Disasm(
256
+ // data,
257
+ // startAddr,
258
+ // 0, // insns to disassemble, 0 for all
259
+ // )
260
+ // if err != nil {
261
+ // return errors.Wrapf(err, "failed to disassemble data")
262
+ // }
263
+
264
+ // for i, insn := range insns {
265
+ // // check for start of a new function
266
+ // if funcStarts != nil && isFunctionStart(funcStarts, uint64(insn.Address)) != 0 {
267
+ // syms, err := m.FindAddressSymbols(uint64(insn.Address))
268
+ // if len(syms) > 1 {
269
+ // log.Warnf("found more than one symbol at address 0x%x, %v", insn.Address, syms)
270
+ // }
271
+ // if err == nil {
272
+ // var symName string
273
+ // if demangleFlag {
274
+ // symName = doDemangle(syms[0].Name)
275
+ // }
276
+ // fmt.Printf("\n%s:\n", symName)
277
+ // }
278
+ // }
279
+
280
+ // // lookup adrp/ldr or add address as a cstring or symbol name
281
+ // if Verbose && (insn.Mnemonic == "ldr" || insn.Mnemonic == "add") && insns[i-1].Mnemonic == "adrp" {
282
+ // if insn.Arm64.Operands != nil && len(insn.Arm64.Operands) > 1 {
283
+ // if insns[i-1].Arm64.Operands != nil && len(insns[i-1].Arm64.Operands) > 1 {
284
+ // adrpRegister := insns[i-1].Arm64.Operands[0].Reg
285
+ // adrpImm := insns[i-1].Arm64.Operands[1].Imm
286
+ // if insn.Mnemonic == "ldr" && adrpRegister == insn.Arm64.Operands[1].Mem.Base {
287
+ // adrpImm += int64(insn.Arm64.Operands[1].Mem.Disp)
288
+ // } else if insn.Mnemonic == "add" && adrpRegister == insn.Arm64.Operands[0].Reg {
289
+ // adrpImm += insn.Arm64.Operands[2].Imm
290
+ // }
291
+ // // markup disassemble with label comment
292
+ // syms, err := m.FindAddressSymbols(uint64(adrpImm))
293
+ // if len(syms) > 1 {
294
+ // log.Warnf("found more than one symbol at address 0x%x, %v", uint64(adrpImm), syms)
295
+ // }
296
+ // if err == nil {
297
+ // var symName string
298
+ // if demangleFlag {
299
+ // symName = doDemangle(syms[0].Name)
300
+ // }
301
+ // insn.OpStr += fmt.Sprintf(" // %s", symName)
302
+ // } else {
303
+ // cstr, err := m.GetCString(uint64(adrpImm))
304
+ // if err == nil {
305
+ // insn.OpStr += fmt.Sprintf(" // %s", cstr)
306
+ // }
307
+ // }
308
+ // }
309
+ // }
310
+ // }
311
+
312
+ // // check if branch location is a function
313
+ // if strings.HasPrefix(insn.Mnemonic, "b") && strings.HasPrefix(insn.OpStr, "#0x") {
314
+ // if insn.Arm64.Operands != nil && len(insn.Arm64.Operands) > 0 {
315
+ // syms, err := m.FindAddressSymbols(uint64(insn.Arm64.Operands[0].Imm))
316
+ // if len(syms) > 1 {
317
+ // log.Warnf("found more than one symbol at address 0x%x, %v", uint64(insn.Arm64.Operands[0].Imm), syms)
318
+ // }
319
+ // if err == nil {
320
+ // var symName string
321
+ // if demangleFlag {
322
+ // symName = doDemangle(syms[0].Name)
323
+ // }
324
+ // insn.OpStr = symName
325
+ // }
326
+ // }
327
+ // }
328
+
329
+ // fmt.Printf("0x%x:\t%s\t\t%s\n", insn.Address, insn.Mnemonic, insn.OpStr)
330
+ // }
331
+
249
332
return nil
250
333
},
251
334
}
0 commit comments