Skip to content

Commit 5d4d18b

Browse files
committed
feat: rm capstone in favor of go-arm64
1 parent c2d529b commit 5d4d18b

File tree

3 files changed

+172
-109
lines changed

3 files changed

+172
-109
lines changed

.github/workflows/go.yml

-6
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,6 @@ jobs:
2222
if: matrix.platform == 'ubuntu-latest'
2323
run: |
2424
sudo apt-get update && sudo apt-get install -y cmake libtool libc6-dev
25-
cd /tmp
26-
git clone -b next https://github.com/aquynh/capstone.git
27-
cd capstone
28-
CAPSTONE_ARCHS="arm aarch64 x86" ./make.sh
29-
sudo ./make.sh install
3025
cd /tmp
3126
git clone https://github.com/lzfse/lzfse.git
3227
cd lzfse
@@ -39,7 +34,6 @@ jobs:
3934
run: |
4035
brew update
4136
brew install lzfse
42-
brew install capstone --HEAD
4337
# - name: Build Dependencies (Windows)
4438
# if: matrix.platform == 'windows-latest'
4539
# run: |

Dockerfile

-14
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,6 @@ RUN \
1818
&& cmake .. \
1919
&& make install
2020

21-
RUN \
22-
echo "===> Installing capstone..." \
23-
&& cd /tmp \
24-
&& git clone -b next https://github.com/aquynh/capstone.git \
25-
&& cd capstone \
26-
&& CAPSTONE_ARCHS="arm aarch64 x86" ./make.sh \
27-
&& ./make.sh install
28-
2921
ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
3022

3123
RUN CGO_ENABLED=1 go build \
@@ -57,12 +49,6 @@ RUN buildDeps='libfuse3-dev bzip2 libbz2-dev libz-dev cmake build-essential git
5749
&& cmake .. \
5850
&& make install \
5951
&& cd /tmp \
60-
&& echo "===> Installing capstone..." \
61-
&& cd /tmp \
62-
&& git clone -b next https://github.com/aquynh/capstone.git \
63-
&& cd capstone \
64-
&& CAPSTONE_ARCHS="arm aarch64 x86" ./make.sh \
65-
&& ./make.sh install \
6652
&& echo "===> Installing apfs-fuse..." \
6753
&& cd /tmp \
6854
&& git clone https://github.com/sgan81/apfs-fuse.git \

cmd/ipsw/cmd/disass.go

+172-89
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// +build !windows,cgo
2-
31
/*
42
Copyright © 2019 blacktop
53
@@ -24,17 +22,19 @@ THE SOFTWARE.
2422
package cmd
2523

2624
import (
25+
"bytes"
2726
"fmt"
2827
"sort"
2928
"strconv"
3029
"strings"
3130

3231
"github.com/apex/log"
32+
"github.com/blacktop/go-arm64"
3333
"github.com/blacktop/go-macho"
3434
"github.com/blacktop/ipsw/internal/demangle"
35-
"github.com/knightsc/gapstone"
3635
"github.com/pkg/errors"
3736
"github.com/spf13/cobra"
37+
// "github.com/knightsc/gapstone"
3838
)
3939

4040
var (
@@ -89,6 +89,13 @@ func isFunctionStart(starts []uint64, addr uint64) uint64 {
8989
return 0
9090
}
9191

92+
func pad(length int) string {
93+
if length > 0 {
94+
return strings.Repeat(" ", length)
95+
}
96+
return " "
97+
}
98+
9299
// disCmd represents the dis command
93100
var disCmd = &cobra.Command{
94101
Use: "disass",
@@ -135,117 +142,193 @@ var disCmd = &cobra.Command{
135142

136143
found := false
137144
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
141148

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+
}
151153

152-
break
154+
_, err := sec.ReadAt(data, int64(memOffset))
155+
if err != nil {
156+
return err
153157
}
158+
159+
break
154160
}
161+
// }
155162
}
156163

157164
if !found {
158165
return fmt.Errorf("supplied vaddr not found in any __text section")
159166
}
160167

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)}) {
182169
// 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())
185172
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)
187174
}
188175
if err == nil {
189176
var symName string
190177
if demangleFlag {
191178
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
223183
}
224184
}
225185
}
186+
fmt.Printf("\n%s:\n", symName)
187+
} else {
188+
fmt.Printf("\nfunc_%x:\n", i.Instruction.Address())
226189
}
227190
}
228191

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())
247241
}
248242

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+
249332
return nil
250333
},
251334
}

0 commit comments

Comments
 (0)