mirror of
https://github.com/blacktop/ipsw.git
synced 2026-05-08 12:22:26 +00:00
add ipsw.me api stuff
This commit is contained in:
+4
-1
@@ -11,4 +11,7 @@
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
dist/
|
||||
dist/
|
||||
*.ipsw
|
||||
get-ipsws
|
||||
caches/
|
||||
+101
@@ -1 +1,102 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
const ipswMeURL = "https://api.ipsw.me/v4/"
|
||||
|
||||
// Device struct
|
||||
type Device struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Identifier string `json:"identifier,omitempty"`
|
||||
BoardConfig string `json:"boardconfig,omitempty"`
|
||||
Platform string `json:"platform,omitempty"`
|
||||
CpID int `json:"cpid,omitempty"`
|
||||
BdID int `json:"bdid,omitempty"`
|
||||
}
|
||||
|
||||
// IPSW struct
|
||||
type IPSW struct {
|
||||
Identifier string `json:"identifier,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
BuildID string `json:"buildid,omitempty"`
|
||||
SHA1 string `json:"sha1sum,omitempty"`
|
||||
MD5 string `json:"md5sum,omitempty"`
|
||||
Filesize int `json:"filesize,omitempty"`
|
||||
URL string `json:"url,omitempty"`
|
||||
ReleaseDate time.Time `json:"releasedate,omitempty"`
|
||||
UploadDate time.Time `json:"uploaddate,omitempty"`
|
||||
Signed bool `json:"signed,omitempty"`
|
||||
}
|
||||
|
||||
// GetDevices returns a list of all devices
|
||||
func GetDevices() []Device {
|
||||
|
||||
res, err := http.Get(ipswMeURL + "devices")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
res.Body.Close()
|
||||
|
||||
devices := []Device{}
|
||||
err = json.Unmarshal(body, &devices)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
return devices
|
||||
}
|
||||
|
||||
// GetAllIPSW finds all IPSW files for a given iOS version
|
||||
func GetAllIPSW(version string) []IPSW {
|
||||
res, err := http.Get(ipswMeURL + "ipsw/" + version)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
res.Body.Close()
|
||||
|
||||
ipsws := []IPSW{}
|
||||
err = json.Unmarshal(body, &ipsws)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
return ipsws
|
||||
}
|
||||
|
||||
// GetIPSW will get an IPSW when supplied an identifier and build ID
|
||||
func GetIPSW(identifier, buildID string) IPSW {
|
||||
res, err := http.Get(ipswMeURL + "ipsw/" + identifier + "/" + buildID)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
i := IPSW{}
|
||||
err = json.Unmarshal(body, &i)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
return i
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
humanize "github.com/dustin/go-humanize"
|
||||
@@ -73,6 +75,69 @@ func DownloadFile(filepath string, url string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Unzip - https://stackoverflow.com/a/24792688
|
||||
func Unzip(src, dest string) error {
|
||||
r, err := zip.OpenReader(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err := r.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
os.MkdirAll(dest, 0755)
|
||||
|
||||
// Closure to address file descriptors issue with all the deferred .Close() methods
|
||||
extractAndWriteFile := func(f *zip.File) error {
|
||||
rc, err := f.Open()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err := rc.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
path := filepath.Join(dest, f.Name)
|
||||
|
||||
if f.FileInfo().IsDir() {
|
||||
os.MkdirAll(path, f.Mode())
|
||||
} else {
|
||||
os.MkdirAll(filepath.Dir(path), f.Mode())
|
||||
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err := f.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
_, err = io.Copy(f, rc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, f := range r.File {
|
||||
if strings.Contains(f.Name, "kernelcache") {
|
||||
err := extractAndWriteFile(f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func multiDownload() error {
|
||||
// res, _ := http.Head("http://localhost/rand.txt") // 187 MB file of random numbers per line
|
||||
// maps := res.Header
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
module github.com/blacktop/get-ipsws
|
||||
|
||||
require (
|
||||
github.com/PuerkitoBio/goquery v1.4.1
|
||||
github.com/andybalholm/cascadia v1.0.0
|
||||
github.com/apex/log v1.0.0
|
||||
github.com/dustin/go-humanize v0.0.0-20180713052910-9f541cc9db5d
|
||||
github.com/pkg/errors v0.8.0
|
||||
github.com/rakyll/statik v0.1.4
|
||||
github.com/urfave/cli v1.20.0
|
||||
golang.org/x/net v0.0.0-20180824152047-4bcd98cce591
|
||||
)
|
||||
@@ -0,0 +1,17 @@
|
||||
github.com/PuerkitoBio/goquery v1.4.1 h1:smcIRGdYm/w7JSbcdeLHEMzxmsBQvl8lhf0dSw2nzMI=
|
||||
github.com/PuerkitoBio/goquery v1.4.1/go.mod h1:T9ezsOHcCrDCgA8aF1Cqr3sSYbO/xgdy8/R/XiIMAhA=
|
||||
github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o=
|
||||
github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||
github.com/apex/log v1.0.0 h1:5UWeZC54mWVtOGSCjtuvDPgY/o0QxmjQgvYZ27pLVGQ=
|
||||
github.com/apex/log v1.0.0/go.mod h1:yA770aXIDQrhVOIGurT/pVdfCpSq1GQV/auzMN5fzvY=
|
||||
github.com/dustin/go-humanize v0.0.0-20180713052910-9f541cc9db5d h1:lDrio3iIdNb0Gw9CgH7cQF+iuB5mOOjdJ9ERNJCBgb4=
|
||||
github.com/dustin/go-humanize v0.0.0-20180713052910-9f541cc9db5d/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/rakyll/statik v0.1.4 h1:zCS/YQCxfo/fQjCtGVGIyWGFnRbQ18Y55mhS3XPE+Oo=
|
||||
github.com/rakyll/statik v0.1.4/go.mod h1:OEi9wJV/fMUAGx1eNjq75DKDsJVuEv1U0oYdX6GX8Zs=
|
||||
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180824152047-4bcd98cce591 h1:4S2XUgvg3hUNTvxI307qkFPb9zKHG3Nf9TXFzX/DZZI=
|
||||
golang.org/x/net v0.0.0-20180824152047-4bcd98cce591/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
Executable
+52
@@ -0,0 +1,52 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Increment a version string using Semantic Versioning (SemVer) terminology.
|
||||
|
||||
# Parse command line options.
|
||||
|
||||
while getopts ":Mmp" Option
|
||||
do
|
||||
case $Option in
|
||||
M ) major=true;;
|
||||
m ) minor=true;;
|
||||
p ) patch=true;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift $(($OPTIND - 1))
|
||||
|
||||
version=$1
|
||||
|
||||
# Build array from version string.
|
||||
|
||||
a=( ${version//./ } )
|
||||
|
||||
# If version string is missing or has the wrong number of members, show usage message.
|
||||
|
||||
if [ ${#a[@]} -ne 3 ]
|
||||
then
|
||||
echo "usage: $(basename $0) [-Mmp] major.minor.patch"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Increment version numbers as requested.
|
||||
|
||||
if [ ! -z $major ]
|
||||
then
|
||||
((a[0]++))
|
||||
a[1]=0
|
||||
a[2]=0
|
||||
fi
|
||||
|
||||
if [ ! -z $minor ]
|
||||
then
|
||||
((a[1]++))
|
||||
a[2]=0
|
||||
fi
|
||||
|
||||
if [ ! -z $patch ]
|
||||
then
|
||||
((a[2]++))
|
||||
fi
|
||||
|
||||
echo "${a[0]}.${a[1]}.${a[2]}"
|
||||
@@ -4,13 +4,16 @@ package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"runtime"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/apex/log"
|
||||
clihander "github.com/apex/log/handlers/cli"
|
||||
"github.com/blacktop/get-ipsws/api"
|
||||
_ "github.com/blacktop/get-ipsws/statik"
|
||||
"github.com/rakyll/statik/fs"
|
||||
"github.com/urfave/cli"
|
||||
@@ -147,7 +150,11 @@ func main() {
|
||||
Name: "generate",
|
||||
Usage: "crawl theiphonewiki.com and create JSON database",
|
||||
Action: func(c *cli.Context) error {
|
||||
ScrapeIPhoneWiki()
|
||||
i := api.GetIPSW("iPhone11,2", "16A366")
|
||||
fmt.Println(i)
|
||||
// DownloadFile(path.Base(i.URL), i.URL)
|
||||
Unzip(path.Base(i.URL), "caches")
|
||||
// ScrapeIPhoneWiki()
|
||||
return nil
|
||||
},
|
||||
},
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package lzss
|
||||
|
||||
import "io"
|
||||
|
||||
// Decompress decompresses lzss data
|
||||
func Decompress(in *io.Reader, out *io.Writer, size uint64) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
// #cgo CFLAGS: -g -Wall
|
||||
// #include "lzss.h"
|
||||
import "C"
|
||||
+3988
File diff suppressed because one or more lines are too long
+106
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* The contents of this file constitute Original Code as defined in and
|
||||
* are subject to the Apple Public Source License Version 1.1 (the
|
||||
* "License"). You may not use this file except in compliance with the
|
||||
* License. Please obtain a copy of the License at
|
||||
* http://www.apple.com/publicsource and read it before using this file.
|
||||
*
|
||||
* This Original Code and all software distributed under the License are
|
||||
* distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
|
||||
* License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/**************************************************************
|
||||
LZSS.C -- A Data Compression Program
|
||||
***************************************************************
|
||||
4/6/1989 Haruhiko Okumura
|
||||
Use, distribute, and modify this program freely.
|
||||
Please send me your improved versions.
|
||||
PC-VAN SCIENCE
|
||||
NIFTY-Serve PAF01022
|
||||
CompuServe 74050,1022
|
||||
|
||||
**************************************************************/
|
||||
/*
|
||||
* lzss.c - Package for decompressing lzss compressed objects
|
||||
*
|
||||
* Copyright (c) 2003 Apple Computer, Inc.
|
||||
*
|
||||
* DRI: Josh de Cesare
|
||||
*/
|
||||
#include "lzss.h"
|
||||
|
||||
#define N 4096 /* size of ring buffer - must be power of 2 */
|
||||
#define F 18 /* upper limit for match_length */
|
||||
#define THRESHOLD 2 /* encode string into position and length \
|
||||
if match_length is greater than this */
|
||||
#define NIL N /* index for root of binary search trees */
|
||||
|
||||
int decompress_lzss(u_int8_t *dst, u_int8_t *src, u_int32_t srclen)
|
||||
{
|
||||
/* ring buffer of size N, with extra F-1 bytes to aid string comparison */
|
||||
u_int8_t text_buf[N + F - 1];
|
||||
u_int8_t *dststart = dst;
|
||||
u_int8_t *srcend = src + srclen;
|
||||
int i, j, k, r, c;
|
||||
unsigned int flags;
|
||||
|
||||
dst = dststart;
|
||||
srcend = src + srclen;
|
||||
for (i = 0; i < N - F; i++)
|
||||
text_buf[i] = ' ';
|
||||
r = N - F;
|
||||
flags = 0;
|
||||
for (;;)
|
||||
{
|
||||
if (((flags >>= 1) & 0x100) == 0)
|
||||
{
|
||||
if (src < srcend)
|
||||
c = *src++;
|
||||
else
|
||||
break;
|
||||
flags = c | 0xFF00; /* uses higher byte cleverly */
|
||||
} /* to count eight */
|
||||
if (flags & 1)
|
||||
{
|
||||
if (src < srcend)
|
||||
c = *src++;
|
||||
else
|
||||
break;
|
||||
*dst++ = c;
|
||||
text_buf[r++] = c;
|
||||
r &= (N - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (src < srcend)
|
||||
i = *src++;
|
||||
else
|
||||
break;
|
||||
if (src < srcend)
|
||||
j = *src++;
|
||||
else
|
||||
break;
|
||||
i |= ((j & 0xF0) << 4);
|
||||
j = (j & 0x0F) + THRESHOLD;
|
||||
for (k = 0; k <= j; k++)
|
||||
{
|
||||
c = text_buf[(i + k) & (N - 1)];
|
||||
*dst++ = c;
|
||||
text_buf[r++] = c;
|
||||
r &= (N - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dst - dststart;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
#include <sl.h>
|
||||
|
||||
#ifndef _LZSS_H
|
||||
#define _LZSS_H
|
||||
|
||||
int decompress_lzss(u_int8_t *dst, u_int8_t *src, u_int32_t srclen);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,287 @@
|
||||
// (C)2009 Willem Hengeveld itsme@xs4all.nl
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
|
||||
// streaming version of the lzss algorithm, as defined in BootX-75/bootx.tproj/sl.subproj/lzss.c
|
||||
// you can use lzssdec in a filter, like:
|
||||
//
|
||||
// cat file.lzss | lzssdec > file.decompressed
|
||||
//
|
||||
static int g_debug = 0;
|
||||
|
||||
class lzssdecompress
|
||||
{
|
||||
enum
|
||||
{
|
||||
COPYFROMDICT,
|
||||
EXPECTINGFLAG,
|
||||
PROCESSFLAGBIT,
|
||||
EXPECTING2NDBYTE
|
||||
};
|
||||
int _state;
|
||||
uint8_t _flags;
|
||||
int _bitnr;
|
||||
uint8_t *_src, *_srcend;
|
||||
uint8_t *_dst, *_dstend;
|
||||
uint8_t _firstbyte;
|
||||
|
||||
uint8_t *_dict;
|
||||
|
||||
int _dictsize;
|
||||
int _maxmatch;
|
||||
int _copythreshold;
|
||||
|
||||
int _dictptr;
|
||||
|
||||
int _copyptr;
|
||||
int _copycount;
|
||||
|
||||
int _inputoffset;
|
||||
int _outputoffset;
|
||||
|
||||
public:
|
||||
lzssdecompress()
|
||||
{
|
||||
_maxmatch = 18; // 4 bit size + threshold
|
||||
_dictsize = 4096; // 12 bit size
|
||||
_copythreshold = 3; // 0 == copy 3 bytes
|
||||
_dict = new uint8_t[_dictsize + _maxmatch - 1];
|
||||
|
||||
reset();
|
||||
}
|
||||
~lzssdecompress()
|
||||
{
|
||||
delete[] _dict;
|
||||
_dict = 0;
|
||||
_dictsize = 0;
|
||||
}
|
||||
void reset()
|
||||
{
|
||||
_state = EXPECTINGFLAG;
|
||||
_flags = 0;
|
||||
_bitnr = 0;
|
||||
_src = _srcend = _dst = _dstend = 0;
|
||||
memset(_dict, ' ', _dictsize + _maxmatch - 1);
|
||||
_dictptr = _dictsize - _maxmatch;
|
||||
_inputoffset = 0;
|
||||
_outputoffset = 0;
|
||||
_firstbyte = 0;
|
||||
_copyptr = 0;
|
||||
_copycount = 0;
|
||||
}
|
||||
void decompress(uint8_t *dst, uint32_t dstlen, uint32_t *pdstused, uint8_t *src, uint32_t srclen, uint32_t *psrcused)
|
||||
{
|
||||
_src = src;
|
||||
_srcend = src + srclen;
|
||||
_dst = dst;
|
||||
_dstend = dst + dstlen;
|
||||
|
||||
while (_src < _srcend && _dst < _dstend)
|
||||
{
|
||||
switch (_state)
|
||||
{
|
||||
case EXPECTINGFLAG:
|
||||
if (g_debug)
|
||||
fprintf(stderr, "%08x,%08x: flag: %02x\n", _inputoffset, _outputoffset, *_src);
|
||||
_flags = *_src++;
|
||||
_inputoffset++;
|
||||
_bitnr = 0;
|
||||
_state = PROCESSFLAGBIT;
|
||||
break;
|
||||
case PROCESSFLAGBIT:
|
||||
if (_flags & 1)
|
||||
{
|
||||
if (g_debug)
|
||||
fprintf(stderr, "%08x,%08x: bit%d: %03x copybyte %02x\n", _inputoffset, _outputoffset, _bitnr, _dictptr, *_src);
|
||||
addtodict(*_dst++ = *_src++);
|
||||
_inputoffset++;
|
||||
_outputoffset++;
|
||||
nextflagbit();
|
||||
}
|
||||
else
|
||||
{
|
||||
_firstbyte = *_src++;
|
||||
_inputoffset++;
|
||||
_state = EXPECTING2NDBYTE;
|
||||
}
|
||||
break;
|
||||
case EXPECTING2NDBYTE:
|
||||
{
|
||||
uint8_t secondbyte = *_src++;
|
||||
_inputoffset++;
|
||||
setcounter(_firstbyte, secondbyte);
|
||||
if (g_debug)
|
||||
fprintf(stderr, "%08x,%08x: bit%d: %03x %02x %02x : copy %d bytes from %03x", _inputoffset - 2, _outputoffset, _bitnr, _dictptr, _firstbyte, secondbyte, _copycount, _copyptr);
|
||||
if (g_debug)
|
||||
dumpcopydata();
|
||||
_state = COPYFROMDICT;
|
||||
}
|
||||
break;
|
||||
case COPYFROMDICT:
|
||||
copyfromdict();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (g_debug)
|
||||
fprintf(stderr, "decompress state= %d, copy: 0x%x, 0x%x\n", _state, _copyptr, _copycount);
|
||||
if (pdstused)
|
||||
*pdstused = _dst - dst;
|
||||
if (psrcused)
|
||||
*psrcused = _src - src;
|
||||
}
|
||||
void flush(uint8_t *dst, uint32_t dstlen, uint32_t *pdstused)
|
||||
{
|
||||
if (g_debug)
|
||||
fprintf(stderr, "flash before state= %d, copy: 0x%x, 0x%x\n", _state, _copyptr, _copycount);
|
||||
_src = _srcend = NULL;
|
||||
_dst = dst;
|
||||
_dstend = dst + dstlen;
|
||||
|
||||
if (_state == COPYFROMDICT)
|
||||
copyfromdict();
|
||||
|
||||
if (pdstused)
|
||||
*pdstused = _dst - dst;
|
||||
if (g_debug)
|
||||
fprintf(stderr, "flash after state= %d, copy: 0x%x, 0x%x\n", _state, _copyptr, _copycount);
|
||||
}
|
||||
void copyfromdict()
|
||||
{
|
||||
while (_dst < _dstend && _copycount)
|
||||
{
|
||||
addtodict(*_dst++ = _dict[_copyptr++]);
|
||||
_outputoffset++;
|
||||
_copycount--;
|
||||
_copyptr = _copyptr & (_dictsize - 1);
|
||||
}
|
||||
if (_copycount == 0)
|
||||
nextflagbit();
|
||||
}
|
||||
void dumpcopydata()
|
||||
{
|
||||
// note: we are printing incorrect data, if _copyptr == _dictptr-1
|
||||
for (int i = 0; i < _copycount; i++)
|
||||
fprintf(stderr, " %02x", _dict[(_copyptr + i) & (_dictsize - 1)]);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
void addtodict(uint8_t c)
|
||||
{
|
||||
_dict[_dictptr++] = c;
|
||||
_dictptr = _dictptr & (_dictsize - 1);
|
||||
}
|
||||
void nextflagbit()
|
||||
{
|
||||
_bitnr++;
|
||||
_flags >>= 1;
|
||||
_state = _bitnr == 8 ? EXPECTINGFLAG : PROCESSFLAGBIT;
|
||||
}
|
||||
void setcounter(uint8_t first, uint8_t second)
|
||||
{
|
||||
_copyptr = first | ((second & 0xf0) << 4);
|
||||
_copycount = _copythreshold + (second & 0xf);
|
||||
}
|
||||
};
|
||||
|
||||
void usage(int argc, char **argv)
|
||||
{
|
||||
char *name = NULL;
|
||||
name = strrchr(argv[0], '/');
|
||||
fprintf(stderr, "Usage: %s [-d] [-o OFFSET] <kernelcache> <output>\n", (name ? name + 1 : argv[0]));
|
||||
}
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// _setmode(fileno(stdin),O_BINARY);
|
||||
// _setmode(fileno(stdout),O_BINARY);
|
||||
|
||||
#define HANDLEULOPTION(var, type) (argv[i][2] ? var = (type)strtoul(argv[i] + 2, 0, 0) : i + 1 < argc ? var = (type)strtoul(argv[++i], 0, 0) : 0)
|
||||
|
||||
uint32_t skipbytes = 0;
|
||||
if (argc < 2)
|
||||
{
|
||||
usage(argc, argv);
|
||||
return 0;
|
||||
}
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
if (argv[i][0] == '-')
|
||||
switch (argv[i][1])
|
||||
{
|
||||
case 'd':
|
||||
g_debug++;
|
||||
if (argv[i][2] == 'd')
|
||||
g_debug++;
|
||||
break;
|
||||
case 'o':
|
||||
HANDLEULOPTION(skipbytes, uint32_t);
|
||||
break;
|
||||
default:
|
||||
usage(argc, argv);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
usage(argc, argv);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#define CHUNK 0x10000
|
||||
|
||||
lzssdecompress lzss;
|
||||
uint8_t *ibuf = (uint8_t *)malloc(CHUNK);
|
||||
uint8_t *obuf = (uint8_t *)malloc(CHUNK);
|
||||
|
||||
// skip first <skipbytes> bytes
|
||||
while (skipbytes && !feof(stdin))
|
||||
{
|
||||
int nr = fread(ibuf, 1, std::min(skipbytes, (uint32_t)CHUNK), stdin);
|
||||
skipbytes -= nr;
|
||||
}
|
||||
|
||||
while (!feof(stdin))
|
||||
{
|
||||
size_t nr = fread(ibuf, 1, CHUNK, stdin);
|
||||
if (nr == 0)
|
||||
{
|
||||
perror("read");
|
||||
return 1;
|
||||
}
|
||||
if (nr == 0)
|
||||
break;
|
||||
|
||||
size_t srcp = 0;
|
||||
while (srcp < nr)
|
||||
{
|
||||
uint32_t dstused;
|
||||
uint32_t srcused;
|
||||
lzss.decompress(obuf, CHUNK, &dstused, ibuf + srcp, nr - srcp, &srcused);
|
||||
srcp += srcused;
|
||||
size_t nw = fwrite(obuf, 1, dstused, stdout);
|
||||
if (nw < dstused)
|
||||
{
|
||||
perror("write");
|
||||
return 1;
|
||||
}
|
||||
if (g_debug)
|
||||
fprintf(stderr, "decompress: 0x%x -> 0x%x\n", srcused, dstused);
|
||||
}
|
||||
}
|
||||
if (g_debug)
|
||||
fprintf(stderr, "done reading\n");
|
||||
uint32_t dstused;
|
||||
lzss.flush(obuf, CHUNK, &dstused);
|
||||
size_t nw = fwrite(obuf, 1, dstused, stdout);
|
||||
if (nw < dstused)
|
||||
{
|
||||
perror("write");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (g_debug)
|
||||
fprintf(stderr, "flush: %d bytes\n", dstused);
|
||||
|
||||
return 0;
|
||||
}
|
||||
+297
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* The contents of this file constitute Original Code as defined in and
|
||||
* are subject to the Apple Public Source License Version 1.1 (the
|
||||
* "License"). You may not use this file except in compliance with the
|
||||
* License. Please obtain a copy of the License at
|
||||
* http://www.apple.com/publicsource and read it before using this file.
|
||||
*
|
||||
* This Original Code and all software distributed under the License are
|
||||
* distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
|
||||
* License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/*
|
||||
* sl.h - Headers for configuring the Secondary Loader
|
||||
*
|
||||
* Copyright (c) 1998-2005 Apple Computer, Inc.
|
||||
*
|
||||
* DRI: Josh de Cesare
|
||||
*/
|
||||
|
||||
#ifndef _BOOTX_SL_H_
|
||||
#define _BOOTX_SL_H_
|
||||
|
||||
// i.e. should we put up our failure screen; else back to OF
|
||||
#define kFailToBoot (1)
|
||||
|
||||
/*
|
||||
|
||||
Memory Map: assumed 96 MB (temporarily bumping to 112 MB for 4359362)
|
||||
|
||||
Physical Address
|
||||
|
||||
Open Firmware Version 3x, 4x, ...
|
||||
00000000 - 00003FFF : Exception Vectors
|
||||
00004000 - 057FFFFF : Free Memory
|
||||
// 05800000 - 05FFFFFF : OF Image (top 8 MB reserved) [96 MB map]
|
||||
06800000 - 06FFFFFF : OF Image (top 8 MB reserved) [112 MB map]
|
||||
|
||||
|
||||
Logical Address
|
||||
|
||||
// 96 MB map (currently unused - 4363357 tracks re-adoption)
|
||||
00000000 - 00003FFF : Exception Vectors
|
||||
00004000 - 03FFFFFF : Kernel Image, Boot Struct and Drivers (~64 MB)
|
||||
04000000 - 04FFFFFF : File Load Area (16 MB) [80 MB]
|
||||
05000000 - 053FFFFF : FS Cache (4 MB) [84 MB]
|
||||
05400000 - 055FFFFF : Malloc Zone (2 MB) [86 MB]
|
||||
05600000 - 057FFFFF : BootX Image (2 MB) [88 MB]
|
||||
05800000 - 05FFFFFF : Unused/OF (8 MB) [96 MB]
|
||||
|
||||
// 112 MB map (per 4359362)
|
||||
00000000 - 00003FFF : Exception Vectors
|
||||
00004000 - 03FFFFFF : Kernel Image, Boot Struct and Drivers (~64 MB)
|
||||
04000000 - 05FFFFFF : File Load Area (32 MB) [96 MB]
|
||||
06000000 - 063FFFFF : FS Cache (4 MB) [100 MB]
|
||||
06400000 - 065FFFFF : Malloc Zone (2 MB) [102 MB]
|
||||
06600000 - 067FFFFF : BootX Image (2 MB) [104 MB]
|
||||
06800000 - 06FFFFFF : Unused/OF (8 MB) [112 MB]
|
||||
*/
|
||||
|
||||
#define kVectorAddr (0x00000000)
|
||||
#define kVectorSize (0x00004000)
|
||||
|
||||
// OF 3.x
|
||||
#define kImageAddr (0x00004000)
|
||||
#define kImageSize (0x03FFC000)
|
||||
|
||||
// OF 1.x 2.x
|
||||
#define kImageAddr0 (0x00004000)
|
||||
#define kImageSize0 (0x002FC000)
|
||||
#define kImageAddr1 (0x00300000)
|
||||
#define kImageSize1 (0x00200000)
|
||||
#define kImageAddr1Phys (0x05800000)
|
||||
#define kImageAddr2 (0x00500000)
|
||||
#define kImageSize2 (0x03B00000)
|
||||
|
||||
#define kLoadAddr (0x04000000)
|
||||
#define kLoadSize (0x02000000) // 32 MB @ 64
|
||||
#define kMaxMKextSize (0x01000000) // only allow 16 MB of drivers
|
||||
|
||||
#define kFSCacheAddr (0x06000000)
|
||||
#define kFSCacheSize (0x00400000) // 4 MB @ 96
|
||||
|
||||
#define kMallocAddr (0x06400000)
|
||||
#define kMallocSize (0x00200000) // 2 MB @ 100
|
||||
|
||||
#define kMallocAddr_H (0x06400000) // ditto for hibernate
|
||||
#define kMallocSize_H (0x00200000)
|
||||
#define kImageAddr_H (0x07000000) // fallback for hiberate image buffer
|
||||
|
||||
// Default Output Level
|
||||
#define kOutputLevelOff (0)
|
||||
#define kOutputLevelFull (16)
|
||||
|
||||
// OF versions
|
||||
#define kOFVersion1x (0x01000000)
|
||||
#define kOFVersion2x (0x02000000)
|
||||
#define kOFVersion3x (0x03000000)
|
||||
#define kOFVersion4x (0x04000000)
|
||||
|
||||
// Device Types
|
||||
enum
|
||||
{
|
||||
kUnknownDeviceType = 0,
|
||||
kNetworkDeviceType,
|
||||
kBlockDeviceType
|
||||
};
|
||||
|
||||
// File Permissions and Types
|
||||
enum
|
||||
{
|
||||
kPermOtherExecute = 1 << 0,
|
||||
kPermOtherWrite = 1 << 1,
|
||||
kPermOtherRead = 1 << 2,
|
||||
kPermGroupExecute = 1 << 3,
|
||||
kPermGroupWrite = 1 << 4,
|
||||
kPermGroupRead = 1 << 5,
|
||||
kPermOwnerExecute = 1 << 6,
|
||||
kPermOwnerWrite = 1 << 7,
|
||||
kPermOwnerRead = 1 << 8,
|
||||
kPermMask = 0x1FF,
|
||||
kOwnerNotRoot = 1 << 9,
|
||||
kFileTypeUnknown = 0x0 << 16,
|
||||
kFileTypeFlat = 0x1 << 16,
|
||||
kFileTypeDirectory = 0x2 << 16,
|
||||
kFileTypeLink = 0x3 << 16,
|
||||
kFileTypeMask = 0x3 << 16
|
||||
};
|
||||
|
||||
// Key Numbers
|
||||
#define kCommandKey (0x200)
|
||||
#define kOptKey (0x201)
|
||||
#define kShiftKey (0x202)
|
||||
#define kControlKey (0x203)
|
||||
#define kDeleteKey (0x204)
|
||||
|
||||
// Mac OS X Booter Signature 'MOSX'
|
||||
#define kMacOSXSignature (0x4D4F5358)
|
||||
|
||||
// Boot Modes
|
||||
enum
|
||||
{
|
||||
kBootModeNormal = 0,
|
||||
kBootModeSafe,
|
||||
kBootModeSecure
|
||||
};
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <ci.h>
|
||||
#include <sl_words.h>
|
||||
#include <libclite.h>
|
||||
#include <fs.h>
|
||||
#include <boot_args.h>
|
||||
|
||||
// types for plist.c
|
||||
typedef enum
|
||||
{
|
||||
kTagTypeNone = 0,
|
||||
kTagTypeDict,
|
||||
kTagTypeKey,
|
||||
kTagTypeString,
|
||||
kTagTypeInteger,
|
||||
kTagTypeData,
|
||||
kTagTypeDate,
|
||||
kTagTypeFalse,
|
||||
kTagTypeTrue,
|
||||
kTagTypeArray
|
||||
} TagType;
|
||||
|
||||
struct Tag
|
||||
{
|
||||
TagType type;
|
||||
char *string;
|
||||
struct Tag *tag;
|
||||
struct Tag *tagNext;
|
||||
};
|
||||
typedef struct Tag Tag, *TagPtr;
|
||||
|
||||
// Externs for main.c
|
||||
extern char *gVectorSaveAddr;
|
||||
extern long gKernelEntryPoint;
|
||||
extern long gDeviceTreeAddr;
|
||||
extern long gDeviceTreeSize;
|
||||
extern long gBootArgsAddr;
|
||||
extern long gBootArgsSize;
|
||||
extern long gSymbolTableAddr;
|
||||
extern long gSymbolTableSize;
|
||||
|
||||
extern long gBootMode;
|
||||
extern long gBootDeviceType;
|
||||
extern long gBootFileType;
|
||||
extern char gHaveKernelCache;
|
||||
extern char gBootDevice[256];
|
||||
extern char gBootFile[256];
|
||||
extern TagPtr gBootDict;
|
||||
|
||||
extern char gTempStr[4096];
|
||||
|
||||
extern long *gDeviceTreeMMTmp;
|
||||
|
||||
extern long gOFVersion;
|
||||
|
||||
extern char *gKeyMap;
|
||||
|
||||
extern long gRootAddrCells;
|
||||
extern long gRootSizeCells;
|
||||
|
||||
extern CICell gChosenPH;
|
||||
extern CICell gOptionsPH;
|
||||
extern CICell gScreenPH;
|
||||
extern CICell gMemoryMapPH;
|
||||
extern CICell gStdOutPH;
|
||||
|
||||
extern CICell gMMUIH;
|
||||
extern CICell gMemoryIH;
|
||||
extern CICell gStdOutIH;
|
||||
extern CICell gKeyboardIH;
|
||||
|
||||
// useful to activate debug logs near when a problem happens
|
||||
//extern int gDebugCount;
|
||||
|
||||
extern long ThinFatBinary(void **binary, unsigned long *length);
|
||||
extern long GetDeviceType(char *devSpec);
|
||||
extern long ConvertFileSpec(char *fileSpec, char *devSpec, char **filePath);
|
||||
extern long MatchThis(CICell phandle, char *string);
|
||||
extern void *AllocateBootXMemory(long size);
|
||||
extern long AllocateKernelMemory(long size);
|
||||
extern long AllocateMemoryRange(char *rangeName, long start, long length);
|
||||
extern unsigned long Adler32(unsigned char *buffer, long length);
|
||||
|
||||
// Externs for macho.c
|
||||
extern long ThinFatBinaryMachO(void **binary, unsigned long *length);
|
||||
extern long DecodeMachO(void *binary);
|
||||
|
||||
// Externs for elf.c
|
||||
extern long ThinFatBinaryElf(void **binary, unsigned long *length);
|
||||
extern long DecodeElf(void *binary);
|
||||
|
||||
// Externs for device_tree.c
|
||||
extern long FlattenDeviceTree(void);
|
||||
extern CICell SearchForNode(CICell ph, long top, char *prop, char *value);
|
||||
extern CICell SearchForNodeMatching(CICell ph, long top, char *value);
|
||||
|
||||
// Externs for display.c
|
||||
extern long InitDisplays(int fill);
|
||||
extern long DrawSplashScreen(long stage);
|
||||
extern long DrawFailedBootPicture(void);
|
||||
extern void GetMainScreenPH(Boot_Video_Ptr video, int setProperties);
|
||||
void SplashPreview(void *src, u_int8_t *saveunder, u_int32_t savelen);
|
||||
void SplashProgress(u_int8_t *saveunder, int32_t firstBlob, int32_t select);
|
||||
|
||||
// Externs for bmdecompress.c
|
||||
extern int DecompressData(void *srcbase, void *dstbase,
|
||||
int dw, int dh, int bytesPerPixel, int rowbytes);
|
||||
|
||||
// Externs for drivers.c
|
||||
extern long LoadDrivers(char *dirPath);
|
||||
|
||||
// Externs for config.c
|
||||
extern long InitConfig(void);
|
||||
extern long ParseConfigFile(char *addr);
|
||||
|
||||
// Externs for lzss.c
|
||||
extern int decompress_lzss(u_int8_t *dst, u_int8_t *src, u_int32_t srclen);
|
||||
|
||||
// Externs for plist.c
|
||||
extern TagPtr GetProperty(TagPtr dict, char *key);
|
||||
extern long ParseXML(char *buffer, TagPtr *dict);
|
||||
extern void FreeTag(TagPtr tag);
|
||||
#if PLIST_DEBUG
|
||||
extern void DumpTag(TagPtr tag, long depth);
|
||||
#endif
|
||||
|
||||
// Externs/types for raid.c
|
||||
typedef struct RAIDMember *RAIDDevicePtr;
|
||||
|
||||
extern int isRAIDPath(char *devSpec);
|
||||
extern int isRAIDDevice(void *ih);
|
||||
extern long LookForRAID(TagPtr bootDict);
|
||||
extern RAIDDevicePtr RAIDOpen(char *devSpec);
|
||||
extern void RAIDClose(RAIDDevicePtr raid);
|
||||
extern long RAIDRead(RAIDDevicePtr raid, long a, long n, long long offset);
|
||||
extern long RAIDSeek(RAIDDevicePtr raid, long long position);
|
||||
|
||||
#endif /* ! _BOOTX_SL_H_ */
|
||||
Reference in New Issue
Block a user