feat: add ipswd /dsc/webkit API route

This commit is contained in:
blacktop
2023-04-18 15:32:34 -06:00
parent 53b7d55e7d
commit 1aadc75eba
11 changed files with 892 additions and 137 deletions
+1 -1
View File
@@ -31,7 +31,7 @@ func AddRoutes(rg *gin.RouterGroup) {
// This will return the daemon version info.
rg.GET("/version", func(c *gin.Context) {
c.JSON(http.StatusOK, types.Version{
ApiVersion: api.DefaultVersion,
APIVersion: api.DefaultVersion,
OSType: runtime.GOOS,
BuilderVersion: types.BuildVersion,
})
+78 -17
View File
@@ -4,11 +4,20 @@ package dsc
import (
"net/http"
"github.com/blacktop/go-macho"
"github.com/blacktop/ipsw/api/types"
cmd "github.com/blacktop/ipsw/internal/commands/dsc"
"github.com/blacktop/ipsw/pkg/dyld"
"github.com/gin-gonic/gin"
)
// swagger:response
type dscImportsResponse struct {
Path string `json:"path,omitempty"`
// swagger:allOf
ImportedBy *cmd.ImportedBy `json:"imported_by,omitempty"`
}
func dscImports(c *gin.Context) {
dscPath := c.Query("path")
if dscPath == "" {
@@ -17,18 +26,25 @@ func dscImports(c *gin.Context) {
}
f, err := dyld.Open(dscPath)
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
c.AbortWithStatusJSON(http.StatusInternalServerError, types.GenericError{Error: err.Error()})
return
}
defer f.Close()
imps, err := cmd.GetDylibsThatImport(f, c.Query("dylib"))
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
c.AbortWithStatusJSON(http.StatusInternalServerError, types.GenericError{Error: err.Error()})
return
}
c.IndentedJSON(http.StatusOK, gin.H{"path": dscPath, "imported_by": imps})
c.IndentedJSON(http.StatusOK, dscImportsResponse{Path: dscPath, ImportedBy: imps})
}
// swagger:response
type dscInfoResponse struct {
Path string `json:"path,omitempty"`
// swagger:allOf
Info *cmd.Info `json:"info,omitempty"`
}
func dscInfo(c *gin.Context) {
@@ -39,49 +55,63 @@ func dscInfo(c *gin.Context) {
}
f, err := dyld.Open(dscPath)
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
c.AbortWithStatusJSON(http.StatusInternalServerError, types.GenericError{Error: err.Error()})
return
}
defer f.Close()
info, err := cmd.GetInfo(f)
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
c.AbortWithStatusJSON(http.StatusInternalServerError, types.GenericError{Error: err.Error()})
return
}
c.IndentedJSON(http.StatusOK, gin.H{"path": dscPath, "info": info})
c.IndentedJSON(http.StatusOK, dscInfoResponse{Path: dscPath, Info: info})
}
// swagger:response
type dscMachoResponse struct {
Path string `json:"path,omitempty"`
// swagger:allOf
Macho *macho.File `json:"macho,omitempty"`
}
func dscMacho(c *gin.Context) {
dscPath := c.Query("path")
f, err := dyld.Open(dscPath)
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
c.AbortWithStatusJSON(http.StatusInternalServerError, types.GenericError{Error: err.Error()})
return
}
defer f.Close()
image, err := f.Image(c.Query("dylib"))
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
c.AbortWithStatusJSON(http.StatusInternalServerError, types.GenericError{Error: err.Error()})
return
}
m, err := image.GetMacho()
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
c.AbortWithStatusJSON(http.StatusInternalServerError, types.GenericError{Error: err.Error()})
return
}
c.IndentedJSON(http.StatusOK, gin.H{"path": dscPath, "macho": m})
c.IndentedJSON(http.StatusOK, dscMachoResponse{Path: dscPath, Macho: m})
}
// swagger:response
type dscStringsResponse struct {
Path string `json:"path,omitempty"`
// swagger:allOf
Strings []cmd.String `json:"strings,omitempty"`
}
func dscStrings(c *gin.Context) {
dscPath := c.Query("path")
f, err := dyld.Open(dscPath)
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
c.AbortWithStatusJSON(http.StatusInternalServerError, types.GenericError{Error: err.Error()})
return
}
defer f.Close()
@@ -89,33 +119,64 @@ func dscStrings(c *gin.Context) {
pattern := c.Query("pattern")
strs, err := cmd.GetStrings(f, pattern)
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
c.AbortWithStatusJSON(http.StatusInternalServerError, types.GenericError{Error: err.Error()})
return
}
c.IndentedJSON(http.StatusOK, gin.H{"path": dscPath, "strings": strs})
c.IndentedJSON(http.StatusOK, dscStringsResponse{Path: dscPath, Strings: strs})
}
// swagger:response
type dscSymbolsResponse struct {
Path string `json:"path,omitempty"`
// swagger:allOf
Symbols []cmd.Symbol `json:"symbols,omitempty"`
}
func dscSymbols(c *gin.Context) {
dscPath := c.Query("path")
f, err := dyld.Open(dscPath)
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
c.AbortWithStatusJSON(http.StatusInternalServerError, types.GenericError{Error: err.Error()})
return
}
defer f.Close()
var lookups []cmd.Symbol
if err := c.ShouldBindJSON(&lookups); err != nil {
c.AbortWithError(http.StatusBadRequest, err)
c.AbortWithStatusJSON(http.StatusBadRequest, types.GenericError{Error: err.Error()})
return
}
syms, err := cmd.GetSymbols(f, lookups)
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
c.AbortWithStatusJSON(http.StatusInternalServerError, types.GenericError{Error: err.Error()})
return
}
c.IndentedJSON(http.StatusOK, gin.H{"path": dscPath, "symbols": syms})
c.IndentedJSON(http.StatusOK, dscSymbolsResponse{Path: dscPath, Symbols: syms})
}
// swagger:response
type dscWebkitResponse struct {
Path string `json:"path,omitempty"`
Webkit string `json:"webkit,omitempty"`
}
func dscWebkit(c *gin.Context) {
dscPath := c.Query("path")
f, err := dyld.Open(dscPath)
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, types.GenericError{Error: err.Error()})
return
}
defer f.Close()
version, err := cmd.GetWebkitVersion(f)
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, types.GenericError{Error: err.Error()})
return
}
c.IndentedJSON(http.StatusOK, dscWebkitResponse{Path: dscPath, Webkit: version})
}
+45 -1
View File
@@ -37,6 +37,9 @@ func AddRoutes(rg *gin.RouterGroup) {
// description: dylib to search for
// required: true
// type: string
// Responses:
// 200: dscImportsResponse
// 500: genericError
dr.GET("/imports", dscImports)
// swagger:route GET /dsc/info DSC getDscInfo
//
@@ -53,6 +56,9 @@ func AddRoutes(rg *gin.RouterGroup) {
// description: path to dyld_shared_cache
// required: true
// type: string
// Responses:
// 200: dscInfoResponse
// 500: genericError
dr.GET("/info", dscInfo)
// swagger:route GET /dsc/macho DSC getDscMacho
//
@@ -74,6 +80,9 @@ func AddRoutes(rg *gin.RouterGroup) {
// description: dylib to search for
// required: true
// type: string
// Responses:
// 200: dscMachoResponse
// 500: genericError
dr.GET("/macho", dscMacho)
// dr.GET("/o2a", handler) // TODO: implement this
// dr.GET("/objc", handler) // TODO: implement this
@@ -102,6 +111,9 @@ func AddRoutes(rg *gin.RouterGroup) {
// description: regex to search for
// required: true
// type: string
// Responses:
// 200: dscStringsResponse
// 500: genericError
dr.GET("/str", dscStrings)
// dr.GET("/stubs", handler) // TODO: implement this
// dr.GET("/swift", handler) // TODO: implement this
@@ -131,8 +143,40 @@ func AddRoutes(rg *gin.RouterGroup) {
// description: path to dyld_shared_cache
// required: true
// type: string
// responses:
// '200':
// description: symbol lookup response
// schema:
// $ref: '#/responses/dscSymbolsResponse'
// '400':
// description: bad request
// schema:
// $ref: '#/responses/genericError'
// '500':
// description: error
// schema:
// $ref: '#/responses/genericError'
dr.POST("/symaddr", dscSymbols)
// dr.GET("/tbd", handler) // TODO: implement this
// dr.GET("/webkit", handler) // TODO: implement this
// swagger:route GET /dsc/webkit DSC getDscWebkit
//
// Webkit
//
// Get <code>webkit</code> version from dylib in the DSC.
//
// Produces:
// - application/json
//
// Parameters:
// + name: path
// in: query
// description: path to dyld_shared_cache
// required: true
// type: string
// Responses:
// 200: dscWebkitResponse
// 500: genericError
dr.GET("/webkit", dscWebkit) // TODO: implement this
// dr.GET("/xref", handler) // TODO: implement this
}
+1 -1
View File
@@ -64,7 +64,7 @@ func AddRoutes(rg *gin.RouterGroup) {
// required: true
// type: string
// Responses:
// default: genericError
// 500: genericError
// 200: kernelcacheVersion
kg.GET("/version", getVersion)
}
+2 -2
View File
@@ -43,7 +43,7 @@ func AddRoutes(rg *gin.RouterGroup) {
// required: true
// type: string
// Responses:
// default: genericError
// 500: genericError
// 200: mountReponse
rg.POST("/mount/:type", func(c *gin.Context) {
ipswPath := filepath.Clean(c.Query("path"))
@@ -80,7 +80,7 @@ func AddRoutes(rg *gin.RouterGroup) {
// description: path to DMG
// type: string
// Responses:
// default: genericError
// 500: genericError
// 200: successResponse
rg.POST("/unmount", func(c *gin.Context) {
ctx := mount.Context{}
+1 -1
View File
@@ -77,7 +77,7 @@ func (s *Server) Start() error {
s.router.GET("/version", func(c *gin.Context) {
c.JSON(http.StatusOK, types.Version{
ApiVersion: api.DefaultVersion,
APIVersion: api.DefaultVersion,
OSType: runtime.GOOS,
BuilderVersion: types.BuildVersion,
})
+176 -8
View File
@@ -94,7 +94,15 @@
"in": "query",
"required": true
}
]
],
"responses": {
"200": {
"$ref": "#/responses/dscImportsResponse"
},
"500": {
"$ref": "#/responses/genericError"
}
}
}
},
"/dsc/info": {
@@ -116,7 +124,15 @@
"in": "query",
"required": true
}
]
],
"responses": {
"200": {
"$ref": "#/responses/dscInfoResponse"
},
"500": {
"$ref": "#/responses/genericError"
}
}
}
},
"/dsc/macho": {
@@ -145,7 +161,15 @@
"in": "query",
"required": true
}
]
],
"responses": {
"200": {
"$ref": "#/responses/dscMachoResponse"
},
"500": {
"$ref": "#/responses/genericError"
}
}
}
},
"/dsc/str": {
@@ -174,7 +198,15 @@
"in": "query",
"required": true
}
]
],
"responses": {
"200": {
"$ref": "#/responses/dscStringsResponse"
},
"500": {
"$ref": "#/responses/genericError"
}
}
}
},
"/dsc/symaddr": {
@@ -211,7 +243,57 @@
"in": "query",
"required": true
}
]
],
"responses": {
"200": {
"description": "symbol lookup response",
"schema": {
"$ref": "#/responses/dscSymbolsResponse"
}
},
"400": {
"description": "bad request",
"schema": {
"$ref": "#/responses/genericError"
}
},
"500": {
"description": "error",
"schema": {
"$ref": "#/responses/genericError"
}
}
}
}
},
"/dsc/webkit": {
"get": {
"description": "Get \u003ccode\u003ewebkit\u003c/code\u003e version from dylib in the DSC.",
"produces": [
"application/json"
],
"tags": [
"DSC"
],
"summary": "Webkit",
"operationId": "getDscWebkit",
"parameters": [
{
"type": "string",
"description": "path to dyld_shared_cache",
"name": "path",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"$ref": "#/responses/dscWebkitResponse"
},
"500": {
"$ref": "#/responses/genericError"
}
}
}
},
"/extract/dmg": {
@@ -765,7 +847,7 @@
"200": {
"$ref": "#/responses/kernelcacheVersion"
},
"default": {
"500": {
"$ref": "#/responses/genericError"
}
}
@@ -830,7 +912,7 @@
"200": {
"$ref": "#/responses/mountReponse"
},
"default": {
"500": {
"$ref": "#/responses/genericError"
}
}
@@ -866,7 +948,7 @@
"200": {
"$ref": "#/responses/successResponse"
},
"default": {
"500": {
"$ref": "#/responses/genericError"
}
}
@@ -884,6 +966,18 @@
}
},
"definitions": {
"Dylib": {
"description": "Dylib is a struct that contains information about a dyld_shared_cache dylib",
"x-go-package": "github.com/blacktop/ipsw/internal/commands/dsc"
},
"ImportedBy": {
"description": "ImportedBy is a struct that contains information about which dyld_shared_cache dylibs import a given dylib",
"x-go-package": "github.com/blacktop/ipsw/internal/commands/dsc"
},
"Info": {
"description": "Info is a struct that contains information about a dyld_shared_cache file",
"x-go-package": "github.com/blacktop/ipsw/internal/commands/dsc"
},
"KernelVersion": {
"title": "KernelVersion represents the kernel version.",
"x-go-package": "github.com/blacktop/ipsw/pkg/kernelcache"
@@ -892,12 +986,78 @@
"title": "LLVMVersion represents the LLVM version used to compile the kernel.",
"x-go-package": "github.com/blacktop/ipsw/pkg/kernelcache"
},
"String": {
"description": "String is a struct that contains information about a dyld_shared_cache string",
"x-go-package": "github.com/blacktop/ipsw/internal/commands/dsc"
},
"Symbol": {
"description": "Symbol is a struct that contains information about a dyld_shared_cache symbol",
"x-go-package": "github.com/blacktop/ipsw/internal/commands/dsc"
}
},
"responses": {
"dscImportsResponse": {
"description": "",
"headers": {
"imported_by": {},
"path": {
"type": "string"
}
}
},
"dscInfoResponse": {
"description": "",
"headers": {
"info": {},
"path": {
"type": "string"
}
}
},
"dscMachoResponse": {
"description": "",
"headers": {
"macho": {},
"path": {
"type": "string"
}
}
},
"dscStringsResponse": {
"description": "",
"headers": {
"path": {
"type": "string"
},
"strings": {
"type": "array",
"items": {}
}
}
},
"dscSymbolsResponse": {
"description": "",
"headers": {
"path": {
"type": "string"
},
"symbols": {
"type": "array",
"items": {}
}
}
},
"dscWebkitResponse": {
"description": "",
"headers": {
"path": {
"type": "string"
},
"webkit": {
"type": "string"
}
}
},
"extractReponse": {
"description": "The extract response message",
"schema": {
@@ -907,6 +1067,14 @@
}
}
},
"genericError": {
"description": "",
"headers": {
"error": {
"type": "string"
}
}
},
"kernelcacheVersion": {
"description": "Version represents the kernel version and LLVM version.",
"headers": {
+8 -3
View File
@@ -7,7 +7,12 @@ var (
// Version is the version struct
type Version struct {
ApiVersion string
OSType string
BuilderVersion string
APIVersion string `json:"api_version,omitempty"`
OSType string `json:"os_type,omitempty"`
BuilderVersion string `json:"builder_version,omitempty"`
}
// swagger:response genericError
type GenericError struct {
Error string `json:"error"`
}
+16 -25
View File
@@ -29,6 +29,7 @@ import (
"strings"
"github.com/apex/log"
dcsCmd "github.com/blacktop/ipsw/internal/commands/dsc"
"github.com/blacktop/ipsw/internal/download"
"github.com/blacktop/ipsw/internal/utils"
"github.com/blacktop/ipsw/pkg/dyld"
@@ -105,14 +106,9 @@ var WebkitCmd = &cobra.Command{
}
defer f.Close()
image, err := f.Image("WebKit")
webkit1, err := dcsCmd.GetWebkitVersion(f)
if err != nil {
return fmt.Errorf("image not in %s: %v", dscPath, err)
}
m, err := image.GetPartialMacho()
if err != nil {
return err
return fmt.Errorf("failed to get WebKit version: %v", err)
}
if diff {
@@ -140,19 +136,14 @@ var WebkitCmd = &cobra.Command{
}
defer f.Close()
image, err := f.Image("WebKit")
webkit2, err := dcsCmd.GetWebkitVersion(f)
if err != nil {
return fmt.Errorf("image not in %s: %v", dscPath2, err)
}
m2, err := image.GetPartialMacho()
if err != nil {
return err
return fmt.Errorf("failed to get WebKit version: %v", err)
}
out, err := utils.GitDiff(
m.SourceVersion().Version.String()+"\n",
m2.SourceVersion().Version.String()+"\n",
webkit1+"\n",
webkit2+"\n",
&utils.GitDiffConfig{Color: viper.GetBool("color"), Tool: viper.GetString("diff-tool")})
if err != nil {
return err
@@ -170,9 +161,9 @@ var WebkitCmd = &cobra.Command{
var svnRev string
if getRev {
log.Info("Querying https://trac.webkit.org...")
ver, rev, err := dyld.ScrapeWebKitTRAC(m.SourceVersion().Version.String())
ver, rev, err := dyld.ScrapeWebKitTRAC(webkit1)
if err != nil {
log.Infof("WebKit Version: %s", m.SourceVersion().Version)
log.Infof("WebKit Version: %s", webkit1)
return err
}
svnRev = fmt.Sprintf("%s (svn rev %s)", ver, rev)
@@ -182,24 +173,24 @@ var WebkitCmd = &cobra.Command{
if len(apiToken) == 0 {
tags, err = download.GetPreprocessedWebKitTags(proxy, insecure)
if err != nil {
log.Infof("WebKit Version: %s", m.SourceVersion().Version)
log.Infof("WebKit Version: %s", webkit1)
return err
}
} else {
tags, err = download.WebKitGraphQLTags(proxy, insecure, apiToken)
if err != nil {
log.Infof("WebKit Version: %s", m.SourceVersion().Version)
log.Infof("WebKit Version: %s", webkit1)
return err
}
}
for _, tag := range tags {
if strings.Contains(tag.Name, m.SourceVersion().Version.String()) {
if strings.Contains(tag.Name, webkit1) {
if asJSON {
b, err := json.Marshal(&struct {
Version string `json:"version"`
Tag download.GithubTag `json:"tag,omitempty"`
}{
Version: m.SourceVersion().Version.String(),
Version: webkit1,
Tag: tag,
})
if err != nil {
@@ -207,7 +198,7 @@ var WebkitCmd = &cobra.Command{
}
fmt.Println(string(b))
} else {
log.Infof("WebKit Version: %s", m.SourceVersion().Version)
log.Infof("WebKit Version: %s", webkit1)
utils.Indent(log.Info, 2)(fmt.Sprintf("Tag: %s", tag.Name))
utils.Indent(log.Info, 2)(fmt.Sprintf("URL: %s", tag.TarURL))
utils.Indent(log.Info, 2)(fmt.Sprintf("Date: %s", tag.Commit.Date.Format("02Jan2006 15:04:05")))
@@ -222,7 +213,7 @@ var WebkitCmd = &cobra.Command{
Version string `json:"version"`
Rev string `json:"rev,omitempty"`
}{
Version: m.SourceVersion().Version.String(),
Version: webkit1,
Rev: svnRev,
})
if err != nil {
@@ -230,7 +221,7 @@ var WebkitCmd = &cobra.Command{
}
fmt.Println(string(b))
} else {
log.Infof("WebKit Version: %s", m.SourceVersion().Version)
log.Infof("WebKit Version: %s", webkit1)
if len(svnRev) > 0 {
utils.Indent(log.Info, 2)(svnRev)
}
+19 -1
View File
@@ -15,12 +15,14 @@ import (
)
// ImportedBy is a struct that contains information about which dyld_shared_cache dylibs import a given dylib
// swagger:model
type ImportedBy struct {
DSC []string `json:"dsc,omitempty"`
Apps []string `json:"apps,omitempty"`
}
// Dylib is a struct that contains information about a dyld_shared_cache dylib
// swagger:model
type Dylib struct {
Index int `json:"index,omitempty"`
Name string `json:"name,omitempty"`
@@ -30,6 +32,7 @@ type Dylib struct {
}
// Info is a struct that contains information about a dyld_shared_cache file
// swagger:model
type Info struct {
Magic string `json:"magic,omitempty"`
UUID string `json:"uuid,omitempty"`
@@ -44,7 +47,6 @@ type Info struct {
}
// Symbol is a struct that contains information about a dyld_shared_cache symbol
//
// swagger:model
type Symbol struct {
// The address of the symbol
@@ -62,6 +64,7 @@ type Symbol struct {
}
// String is a struct that contains information about a dyld_shared_cache string
// swagger:model
type String struct {
Address uint64 `json:"address,omitempty"`
Image string `json:"image,omitempty"`
@@ -365,3 +368,18 @@ func GetStrings(f *dyld.File, pattern string) ([]String, error) {
return strs, nil
}
// GetWebkitVersion returns the WebKit version from a dyld_shared_cache file
func GetWebkitVersion(f *dyld.File) (string, error) {
image, err := f.Image("WebKit")
if err != nil {
return "", fmt.Errorf("image not in DSC: %v", err)
}
m, err := image.GetPartialMacho()
if err != nil {
return "", fmt.Errorf("failed to create MachO for image %s: %v", image.Name, err)
}
return m.SourceVersion().Version.String(), nil
}
+545 -77
View File
@@ -1,7 +1,13 @@
{
"consumes": ["application/json"],
"produces": ["application/json"],
"schemes": ["http"],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"schemes": [
"http"
],
"swagger": "2.0",
"info": {
"description": "This allows you to interact with \u003ccode\u003eipsw\u003c/code\u003e in a VERY powerful and flexible way via a RESTful API.\n\nThe \u003ccode\u003eipswd\u003c/code\u003e design was heavily influenced by the design of dockerd. So many of the same concepts apply.",
@@ -14,13 +20,17 @@
"/_ping": {
"get": {
"description": "This will return \"OK\" if the daemon is running.",
"tags": ["Daemon"],
"tags": [
"Daemon"
],
"summary": "Ping",
"operationId": "getDaemonPing"
},
"head": {
"description": "This will return if 200 the daemon is running.",
"tags": ["Daemon"],
"tags": [
"Daemon"
],
"summary": "Ping",
"operationId": "headDaemonPing"
}
@@ -28,8 +38,12 @@
"/device_list": {
"get": {
"description": "This will return JSON of all XCode devices.",
"produces": ["application/json"],
"tags": ["DeviceList"],
"produces": [
"application/json"
],
"tags": [
"DeviceList"
],
"summary": "List XCode Devices.",
"operationId": "getDeviceList"
}
@@ -37,7 +51,9 @@
"/download/ipsw/ios/latest/build": {
"get": {
"description": "Get latest iOS build.",
"tags": ["Download"],
"tags": [
"Download"
],
"summary": "Latest iOS Build",
"operationId": "getDownloadLatestIPSWsBuild"
}
@@ -45,7 +61,9 @@
"/download/ipsw/ios/latest/version": {
"get": {
"description": "Get latest iOS version.",
"tags": ["Download"],
"tags": [
"Download"
],
"summary": "Latest iOS Version",
"operationId": "getDownloadLatestIPSWsVersion"
}
@@ -53,8 +71,12 @@
"/dsc/imports": {
"get": {
"description": "Get list of dylibs that import a given dylib.",
"produces": ["application/json"],
"tags": ["DSC"],
"produces": [
"application/json"
],
"tags": [
"DSC"
],
"summary": "Imports",
"operationId": "getDscImports",
"parameters": [
@@ -72,14 +94,26 @@
"in": "query",
"required": true
}
]
],
"responses": {
"200": {
"$ref": "#/responses/dscImportsResponse"
},
"500": {
"$ref": "#/responses/genericError"
}
}
}
},
"/dsc/info": {
"get": {
"description": "Get info about a given DSC",
"produces": ["application/json"],
"tags": ["DSC"],
"produces": [
"application/json"
],
"tags": [
"DSC"
],
"summary": "Info",
"operationId": "getDscInfo",
"parameters": [
@@ -90,14 +124,26 @@
"in": "query",
"required": true
}
]
],
"responses": {
"200": {
"$ref": "#/responses/dscInfoResponse"
},
"500": {
"$ref": "#/responses/genericError"
}
}
}
},
"/dsc/macho": {
"get": {
"description": "Get MachO info for a given dylib in the DSC.",
"produces": ["application/json"],
"tags": ["DSC"],
"produces": [
"application/json"
],
"tags": [
"DSC"
],
"summary": "MachO",
"operationId": "getDscMacho",
"parameters": [
@@ -115,14 +161,26 @@
"in": "query",
"required": true
}
]
],
"responses": {
"200": {
"$ref": "#/responses/dscMachoResponse"
},
"500": {
"$ref": "#/responses/genericError"
}
}
}
},
"/dsc/str": {
"get": {
"description": "Get strings in the DSC that match a given pattern.",
"produces": ["application/json"],
"tags": ["DSC"],
"produces": [
"application/json"
],
"tags": [
"DSC"
],
"summary": "Strings",
"operationId": "getDscStrings",
"parameters": [
@@ -140,17 +198,85 @@
"in": "query",
"required": true
}
]
],
"responses": {
"200": {
"$ref": "#/responses/dscStringsResponse"
},
"500": {
"$ref": "#/responses/genericError"
}
}
}
},
"/dsc/symaddr": {
"get": {
"description": "Get symbols addresses in the DSC that match a given lookup JSON payload.",
"consumes": ["application/json"],
"produces": ["application/json"],
"tags": ["DSC"],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"DSC"
],
"summary": "Symbols",
"operationId": "getDscSymbols",
"parameters": [
{
"description": "Symbol lookups",
"name": "lookups",
"in": "body",
"required": true,
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/Symbol"
}
}
},
{
"type": "string",
"description": "path to dyld_shared_cache",
"name": "path",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "symbol lookup response",
"schema": {
"$ref": "#/responses/dscSymbolsResponse"
}
},
"400": {
"description": "bad request",
"schema": {
"$ref": "#/responses/genericError"
}
},
"500": {
"description": "error",
"schema": {
"$ref": "#/responses/genericError"
}
}
}
}
},
"/dsc/webkit": {
"get": {
"description": "Get \u003ccode\u003ewebkit\u003c/code\u003e version from dylib in the DSC.",
"produces": [
"application/json"
],
"tags": [
"DSC"
],
"summary": "Webkit",
"operationId": "getDscWebkit",
"parameters": [
{
"type": "string",
@@ -159,15 +285,29 @@
"in": "query",
"required": true
}
]
],
"responses": {
"200": {
"$ref": "#/responses/dscWebkitResponse"
},
"500": {
"$ref": "#/responses/genericError"
}
}
}
},
"/extract/dmg": {
"post": {
"description": "Extract DMGs from an IPSW.",
"consumes": ["application/json"],
"produces": ["application/json"],
"tags": ["Extract"],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Extract"
],
"summary": "DMG",
"operationId": "getExtractDmg",
"parameters": [
@@ -204,15 +344,29 @@
}
}
}
]
],
"responses": {
"200": {
"description": "extraction response",
"schema": {
"$ref": "#/responses/extractReponse"
}
}
}
}
},
"/extract/dsc": {
"post": {
"description": "Extract dyld_shared_caches from an IPSW.",
"consumes": ["application/json"],
"produces": ["application/json"],
"tags": ["Extract"],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Extract"
],
"summary": "DSC",
"operationId": "getExtractDsc",
"parameters": [
@@ -252,15 +406,29 @@
}
}
}
]
],
"responses": {
"200": {
"description": "extraction response",
"schema": {
"$ref": "#/responses/extractReponse"
}
}
}
}
},
"/extract/kbag": {
"post": {
"description": "Extract KBAGs from an IPSW.",
"consumes": ["application/json"],
"produces": ["application/json"],
"tags": ["Extract"],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Extract"
],
"summary": "KBAG",
"operationId": "getExtractKbags",
"parameters": [
@@ -296,15 +464,29 @@
}
}
}
]
],
"responses": {
"200": {
"description": "extraction response",
"schema": {
"$ref": "#/responses/extractReponse"
}
}
}
}
},
"/extract/kernel": {
"post": {
"description": "Extract kernelcaches from an IPSW.",
"consumes": ["application/json"],
"produces": ["application/json"],
"tags": ["Extract"],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Extract"
],
"summary": "Kernel",
"operationId": "getExtractKernel",
"parameters": [
@@ -337,15 +519,29 @@
}
}
}
]
],
"responses": {
"200": {
"description": "extraction response",
"schema": {
"$ref": "#/responses/extractReponse"
}
}
}
}
},
"/extract/pattern": {
"post": {
"description": "Extract files from an IPSW that match a given pattern.",
"consumes": ["application/json"],
"produces": ["application/json"],
"tags": ["Extract"],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Extract"
],
"summary": "Pattern",
"operationId": "getExtractPattern",
"parameters": [
@@ -384,13 +580,23 @@
}
}
}
]
],
"responses": {
"200": {
"description": "extraction response",
"schema": {
"$ref": "#/responses/extractReponse"
}
}
}
}
},
"/idev/info": {
"get": {
"description": "Get info about USB connected devices.",
"tags": ["USB"],
"tags": [
"USB"
],
"summary": "Info",
"operationId": "getIdevInfo"
}
@@ -398,8 +604,12 @@
"/info/ipsw": {
"get": {
"description": "Get IPSW info.",
"produces": ["application/json"],
"tags": ["Info"],
"produces": [
"application/json"
],
"tags": [
"Info"
],
"summary": "IPSW",
"operationId": "getIpswInfo",
"parameters": [
@@ -416,8 +626,12 @@
"/info/ipsw/remote": {
"get": {
"description": "Get remote IPSW info.",
"produces": ["application/json"],
"tags": ["Info"],
"produces": [
"application/json"
],
"tags": [
"Info"
],
"summary": "Remote IPSW",
"operationId": "getRemoteIpswInfo",
"parameters": [
@@ -446,8 +660,12 @@
"/info/ota": {
"get": {
"description": "Get OTA info.",
"produces": ["application/json"],
"tags": ["Info"],
"produces": [
"application/json"
],
"tags": [
"Info"
],
"summary": "OTA",
"operationId": "getOtaInfo",
"parameters": [
@@ -464,8 +682,12 @@
"/info/ota/remote": {
"get": {
"description": "Get remote OTA info.",
"produces": ["application/json"],
"tags": ["Info"],
"produces": [
"application/json"
],
"tags": [
"Info"
],
"summary": "Remote OTA",
"operationId": "getRemoteOtaInfo",
"parameters": [
@@ -494,8 +716,12 @@
"/ipsw/fs/ents": {
"get": {
"description": "Get IPSW Filesystem DMG MachO entitlements.",
"produces": ["application/json"],
"tags": ["IPSW"],
"produces": [
"application/json"
],
"tags": [
"IPSW"
],
"summary": "Entitlements",
"operationId": "getIpswFsEntitlements",
"parameters": [
@@ -512,8 +738,12 @@
"/ipsw/fs/files": {
"get": {
"description": "Get IPSW Filesystem DMG file listing.",
"produces": ["application/json"],
"tags": ["IPSW"],
"produces": [
"application/json"
],
"tags": [
"IPSW"
],
"summary": "Files",
"operationId": "getIpswFsFiles",
"parameters": [
@@ -530,8 +760,12 @@
"/ipsw/fs/launchd": {
"get": {
"description": "Get \u003ccode\u003elaunchd\u003c/code\u003e config from IPSW Filesystem DMG.",
"produces": ["application/json"],
"tags": ["IPSW"],
"produces": [
"application/json"
],
"tags": [
"IPSW"
],
"summary": "launchd Config",
"operationId": "getIpswFsLaunchd",
"parameters": [
@@ -548,8 +782,12 @@
"/kernel/kexts": {
"get": {
"description": "Get kernelcache KEXTs info.",
"produces": ["application/json"],
"tags": ["Kernel"],
"produces": [
"application/json"
],
"tags": [
"Kernel"
],
"summary": "Kexts",
"operationId": "getKernelKexts",
"parameters": [
@@ -566,8 +804,12 @@
"/kernel/syscall": {
"get": {
"description": "Get kernelcache syscalls info.",
"produces": ["application/json"],
"tags": ["Kernel"],
"produces": [
"application/json"
],
"tags": [
"Kernel"
],
"summary": "Syscalls",
"operationId": "getKernelSyscalls",
"parameters": [
@@ -584,8 +826,12 @@
"/kernel/version": {
"get": {
"description": "Get kernelcache version.",
"produces": ["application/json"],
"tags": ["Kernel"],
"produces": [
"application/json"
],
"tags": [
"Kernel"
],
"summary": "Version",
"operationId": "getKernelVersion",
"parameters": [
@@ -596,14 +842,26 @@
"in": "query",
"required": true
}
]
],
"responses": {
"200": {
"$ref": "#/responses/kernelcacheVersion"
},
"500": {
"$ref": "#/responses/genericError"
}
}
}
},
"/macho/info": {
"get": {
"description": "Get MachO info.",
"produces": ["application/json"],
"tags": ["MachO"],
"produces": [
"application/json"
],
"tags": [
"MachO"
],
"summary": "Info",
"operationId": "getMachoInfo",
"parameters": [
@@ -626,8 +884,12 @@
"/mount/{type}": {
"post": {
"description": "Mount a DMG inside a given IPSW.",
"produces": ["application/json"],
"tags": ["Mount"],
"produces": [
"application/json"
],
"tags": [
"Mount"
],
"summary": "Mount",
"operationId": "postMount",
"parameters": [
@@ -645,14 +907,26 @@
"in": "query",
"required": true
}
]
],
"responses": {
"200": {
"$ref": "#/responses/mountReponse"
},
"500": {
"$ref": "#/responses/genericError"
}
}
}
},
"/unmount": {
"post": {
"description": "Unmount a previously mounted DMG.",
"produces": ["application/json"],
"tags": ["Mount"],
"produces": [
"application/json"
],
"tags": [
"Mount"
],
"summary": "Unmount",
"operationId": "postUnmount",
"parameters": [
@@ -669,16 +943,210 @@
"name": "dmg_path",
"in": "query"
}
]
],
"responses": {
"200": {
"$ref": "#/responses/successResponse"
},
"500": {
"$ref": "#/responses/genericError"
}
}
}
},
"/version": {
"get": {
"description": "This will return the daemon version info.",
"tags": ["Daemon"],
"tags": [
"Daemon"
],
"summary": "Version",
"operationId": "getDaemonVersion"
}
}
},
"definitions": {
"Dylib": {
"description": "Dylib is a struct that contains information about a dyld_shared_cache dylib",
"x-go-package": "github.com/blacktop/ipsw/internal/commands/dsc"
},
"ImportedBy": {
"description": "ImportedBy is a struct that contains information about which dyld_shared_cache dylibs import a given dylib",
"x-go-package": "github.com/blacktop/ipsw/internal/commands/dsc"
},
"Info": {
"description": "Info is a struct that contains information about a dyld_shared_cache file",
"x-go-package": "github.com/blacktop/ipsw/internal/commands/dsc"
},
"KernelVersion": {
"title": "KernelVersion represents the kernel version.",
"x-go-package": "github.com/blacktop/ipsw/pkg/kernelcache"
},
"LLVMVersion": {
"title": "LLVMVersion represents the LLVM version used to compile the kernel.",
"x-go-package": "github.com/blacktop/ipsw/pkg/kernelcache"
},
"String": {
"description": "String is a struct that contains information about a dyld_shared_cache string",
"x-go-package": "github.com/blacktop/ipsw/internal/commands/dsc"
},
"Symbol": {
"description": "Symbol is a struct that contains information about a dyld_shared_cache symbol",
"x-go-package": "github.com/blacktop/ipsw/internal/commands/dsc"
}
},
"responses": {
"dscImportsResponse": {
"description": "",
"headers": {
"imported_by": {},
"path": {
"type": "string"
}
}
},
"dscInfoResponse": {
"description": "",
"headers": {
"info": {},
"path": {
"type": "string"
}
}
},
"dscMachoResponse": {
"description": "",
"headers": {
"macho": {},
"path": {
"type": "string"
}
}
},
"dscStringsResponse": {
"description": "",
"headers": {
"path": {
"type": "string"
},
"strings": {
"type": "array",
"items": {}
}
}
},
"dscSymbolsResponse": {
"description": "",
"headers": {
"path": {
"type": "string"
},
"symbols": {
"type": "array",
"items": {}
}
}
},
"dscWebkitResponse": {
"description": "",
"headers": {
"path": {
"type": "string"
},
"webkit": {
"type": "string"
}
}
},
"extractReponse": {
"description": "The extract response message",
"schema": {
"type": "array",
"items": {
"type": "string"
}
}
},
"genericError": {
"description": "",
"headers": {
"error": {
"type": "string"
}
}
},
"kernelcacheVersion": {
"description": "Version represents the kernel version and LLVM version.",
"headers": {
"arch": {
"type": "string",
"description": "The kernel architecture"
},
"clang": {
"type": "string",
"description": "The LLVM compiler"
},
"cpu": {
"type": "string",
"description": "The kernel CPU"
},
"darwin": {
"type": "string",
"description": "The darwin version"
},
"date": {
"type": "string",
"format": "date-time",
"description": "The build date"
},
"flags": {
"type": "array",
"items": {
"type": "string"
},
"description": "The LLVM compiler flags"
},
"rawKernel": {
"type": "string"
},
"rawLLVM": {
"type": "string"
},
"type": {
"type": "string",
"description": "The kernel type"
},
"version": {
"type": "string",
"description": "The LLVM version"
},
"xnu": {
"type": "string",
"description": "The xnu version"
}
}
},
"mountReponse": {
"description": "",
"headers": {
"already_mounted": {
"type": "boolean"
},
"dmg_path": {
"type": "string"
},
"mount_point": {
"type": "string"
}
}
},
"successResponse": {
"description": "",
"headers": {
"success": {
"type": "boolean"
}
}
}
}
}
}