├── .gitignore ├── .gitmodules ├── Decoders ├── MuchSad │ └── dogekrypt.java ├── TauSpy-iBanking │ ├── decrypt-d.sh │ ├── decrypt-e.sh │ ├── mcrypt.java │ └── rollingobfuscation.java ├── androrat │ └── extract-config.sh ├── decode_kakabet.rb ├── dendroid │ └── extract-config.sh ├── imogui │ └── imocrypto.java ├── rstealer │ ├── RazStealerDecrypter.1sc │ ├── extract-config.sh │ └── razstealer_decoder.java ├── scaremenot.b │ └── scaremenot_b_decode.java ├── simplocker.c │ ├── extract-data.sh │ └── simplocker_gen.java ├── simplocker.d │ └── simplocker_d_decoder.java └── spyeye.a │ └── spyeye_decode.java ├── IDA ├── IDA_JNI_Rename │ ├── ReadMe.md │ ├── ida_jni.py │ └── jni-api19.h ├── aarch64_func_prolog_finder.py ├── aarch64_func_prolog_finder_s9.py ├── android_jni_assist.py ├── dalvik-rename.idc ├── dbg_dalvik.cfg ├── ida_color_schema.clr ├── import_kallsyms.py ├── jaigu_assist.py ├── raxir_decrypter.py └── xorish.py ├── README.md ├── file └── java └── shell ├── batch-baksmali ├── ida_android ├── int_strings ├── pullapk └── wrapapk /.gitignore: -------------------------------------------------------------------------------- 1 | *~ -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "visualization/droidgraph"] 2 | path = visualization/droidgraph 3 | url = https://github.com/DarioI/droidgraph 4 | -------------------------------------------------------------------------------- /Decoders/MuchSad/dogekrypt.java: -------------------------------------------------------------------------------- 1 | /** 2 | * "Krypt" class from the CoinKrypt.A/B (MuchSad.A) Android malware 3 | * used to decrypt the simply obfuscated strings 4 | * in the Main class. Most used for the tracker/ 5 | * mining args 6 | * 7 | * Strings / Code reversed from 8 | * SHA1: bc27f10178e2bfae277a5b97f1730da5822e4543 9 | * cc8c9ea51a2bdefb4ce9b866eec73a02571bc344 10 | * 11 | * @author Tim "diff" Strazzere 12 | * 13 | * 14 | */ 15 | public class dogekrypt { 16 | 17 | public static void main(String[] args) { 18 | String[] encrypted_sample1 = { 19 | "uggc://cbbyfnghea.serr-u.arg/cbby.cuc?c=qngn", 20 | "uggc://cbbyfnghea.serr-u.arg/hcqngr.cuc?c=qngn", 21 | "/yvopchzvare.fb --nytb=fpelcg -b uggc://sybj.ybtvagb.zr:9555 -B Q7A6H92Ncdju1NzO4ElMKfIAXUfYDuTYeN:k -e 20 -g 1 -O -d", 22 | "/yvopchzvare.fb --nytb=fpelcg -b uggc://sybj.ybtvagb.zr:9555 -B Q7A6H92Ncdju1NzO4ElMKfIAXUfYDuTYeN:k -e 20 -g 1 -O -d;", 23 | "/yvopchzvareARBA.fb --nytb=fpelcg -b uggc://sybj.ybtvagb.zr:9555 -B Q7A6H92Ncdju1NzO4ElMKfIAXUfYDuTYeN:k -e 20 -g 1 -O -d", 24 | "/yvopchzvareARBA.fb --nytb=fpelcg -b uggc://sybj.ybtvagb.zr:9555 -B Q7A6H92Ncdju1NzO4ElMKfIAXUfYDuTYeN:k -e 20 -g 1 -O -d;", 25 | "uggc://cbbyfnghea.serr-u.arg/ertvfgre.cuc?vq=" 26 | }; 27 | 28 | String[] encrypted_sample2 = { 29 | "/FreivprCebivqre --hey=uggc://91.234.105.69:9327 --hfrecnff=YoULkLThLHRReqcx9L63cvW1N4dW3gAtw1:k --guernqf=1 --ergevrf=5;", 30 | "/FreivprCebivqre --hey=uggc://91.234.105.69:9327 --hfrecnff=YoULkLThLHRReqcx9L63cvW1N4dW3gAtw1:k --guernqf=1 --ergevrf=5", 31 | "fbheaq.ab-vc.ovm", 32 | "uggc://sybjfhes.btfcl.arg/zvare.cuc" 33 | }; 34 | 35 | String[] encrypted_sample3 = { 36 | "/yvopchzvareARBA.fb --nytb=fpelcg -b uggc://91.234.105.102:9327 -B YIzQ5FsPDMYmoci1pS63hqftg8M9T97nrO:k -e 20 -g 1 -O -d;", 37 | "/yvopchzvareARBA.fb --nytb=fpelcg -b uggc://91.234.105.102:9327 -B YIzQ5FsPDMYmoci1pS63hqftg8M9T97nrO:k -e 20 -g 1 -O -d", 38 | "/yvopchzvare.fb --nytb=fpelcg -b uggc://91.234.105.102:9327 -B YIzQ5FsPDMYmoci1pS63hqftg8M9T97nrO:k -e 20 -g 1 -O -d;", 39 | "/yvopchzvare.fb --nytb=fpelcg -b uggc://91.234.105.102:9327 -B YIzQ5FsPDMYmoci1pS63hqftg8M9T97nrO:k -e 20 -g 1 -O -d" 40 | }; 41 | 42 | for( String crypted : encrypted_sample1) 43 | System.out.println(doConvert(crypted)); 44 | 45 | for( String crypted : encrypted_sample2) 46 | System.out.println(doConvert(crypted)); 47 | 48 | for( String crypted : encrypted_sample3) 49 | System.out.println(doConvert(crypted)); 50 | } 51 | 52 | private static byte abyte; 53 | 54 | /** 55 | * Black magic; this crypto is insanity 56 | * 57 | * TODO: Hire this author for my next project 58 | */ 59 | public static String doConvert(String in) { 60 | StringBuffer tempReturn = new StringBuffer(); 61 | 62 | for(int i = 0; i < in.length(); i++) { 63 | abyte = (byte) in.charAt(i); 64 | int cap = abyte & 0x20; 65 | abyte &= (cap ^ -1); 66 | 67 | // Is not an alpha capital char? 68 | if(abyte >= 0x41 && abyte <= 0x5A) { 69 | abyte += -0x41; 70 | abyte += 0xD; 71 | abyte %= 0x1A; 72 | abyte += 0x41; 73 | } 74 | abyte = (byte) (cap | abyte); 75 | tempReturn.append((char) abyte); 76 | } 77 | 78 | return tempReturn.toString(); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Decoders/TauSpy-iBanking/decrypt-d.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | java mcrypt f9b681dfa702fac1 MIIBIjANBgkqhkiG $@ -------------------------------------------------------------------------------- /Decoders/TauSpy-iBanking/decrypt-e.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | java rollingobfuscation $@ -------------------------------------------------------------------------------- /Decoders/TauSpy-iBanking/mcrypt.java: -------------------------------------------------------------------------------- 1 | /** 2 | * "MCrypt" class from the iBanking/TauSpy Android malware, 3 | * used to decrypt the aes encrypted strings 4 | * in the Main class. 5 | * 6 | * @author Tim "diff" Strazzere 7 | * 8 | * 9 | */ 10 | 11 | import javax.crypto.Cipher; 12 | import javax.crypto.SecretKey; 13 | import javax.crypto.spec.IvParameterSpec; 14 | import javax.crypto.spec.SecretKeySpec; 15 | 16 | 17 | public class mcrypt { 18 | 19 | public static byte[] iv; 20 | public static SecretKey key; 21 | public static Cipher cipher; 22 | 23 | public static void main(String[] args) { 24 | if(args.length < 3) { 25 | System.out.println("Error; must include three args, ivString, keyString and text to decrypt"); 26 | return; 27 | } 28 | initialize(args[0], args[1]); 29 | for(int i = 2; i < args.length; i++) { 30 | System.out.println(new String(decrypt(args[i]))); 31 | } 32 | } 33 | 34 | public static byte[] hexStringToByteArray(String s) { 35 | int len = s.length(); 36 | byte[] data = new byte[len / 2]; 37 | for (int i = 0; i < len; i += 2) { 38 | data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) 39 | + Character.digit(s.charAt(i+1), 16)); 40 | } 41 | return data; 42 | } 43 | 44 | public static void initialize(String ivString, String keyString) { 45 | iv = ivString.getBytes(); 46 | byte[] keyBytes = keyString.getBytes(); 47 | 48 | key = new SecretKeySpec(keyBytes, "AES"); 49 | try { 50 | cipher = Cipher.getInstance("AES/CBC/NOPADDING"); 51 | } catch (Exception e) { 52 | e.printStackTrace(); 53 | } 54 | } 55 | 56 | public static byte[] decrypt(String input) { 57 | if(input.length() > 0){ 58 | try { 59 | cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv)); 60 | byte[] decrypted = cipher.doFinal(hexStringToByteArray(input)); 61 | // Strip padding (weird way to do it, but same way malware does) 62 | int trim = 0; 63 | for(int i = decrypted.length - 1; i >= 0 ; i--) { 64 | if(decrypted[i] == 0) { 65 | trim++; 66 | } 67 | } 68 | byte[] trimmed = new byte[decrypted.length - trim]; 69 | System.arraycopy(decrypted, 0, trimmed, 0, decrypted.length - trim); 70 | return trimmed; 71 | } catch (Exception e) { 72 | e.printStackTrace(); 73 | } 74 | } 75 | return null; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Decoders/TauSpy-iBanking/rollingobfuscation.java: -------------------------------------------------------------------------------- 1 | /** 2 | * "MCrypt" class from the iBanking/TauSpy Android malware, 3 | * used to decrypt the simply obfuscated strings 4 | * in the Main class. 5 | * 6 | * @author Tim "diff" Strazzere 7 | * 8 | * 9 | */ 10 | public class rollingobfuscation { 11 | 12 | // the first argument should be the rolling modifier to start with 13 | public static void main(String[] args) { 14 | if(args.length < 2) { 15 | System.out.println("Error: please provide a modifier value and atleast on string to decrypt!\n"); 16 | return; 17 | } 18 | 19 | for(int i = 1; i < args.length; i++) { 20 | System.out.println(decode(args[0], hexStringToString(args[i]))); 21 | } 22 | } 23 | 24 | public static String decode(String modifier, String data) { 25 | data = transform(Long.parseLong(modifier), data); 26 | 27 | // Chop off prefix and add + 28 | if(data.startsWith("011")) { 29 | data = "+" + data.substring(3); 30 | } 31 | 32 | return data; 33 | } 34 | 35 | public static String transform(long modifier, String data) { 36 | StringBuffer transformed = new StringBuffer(); 37 | 38 | long current_char; 39 | for(int i = 0; i < data.length(); i++){ 40 | current_char = (long)data.charAt(i); 41 | transformed.append((char)(current_char ^ (modifier >> 8))); 42 | modifier += current_char; 43 | modifier *= 0xCE6D; 44 | modifier += 0x58BF; 45 | modifier %= 0x10000; 46 | } 47 | 48 | return transformed.toString(); 49 | } 50 | 51 | public static String hexStringToString(String string) { 52 | StringBuffer output = new StringBuffer(); 53 | char[] chars = string.toCharArray(); 54 | 55 | for(int i = 0; i < chars.length - 1; i+= 2) { 56 | output.append((char)((Character.digit(chars[i], 0x10) * 0x10) + Character.digit(chars[i+1], 0x10))); 57 | } 58 | 59 | return output.toString(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Decoders/androrat/extract-config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | get_normal_variable() { 4 | echo `grep -A 2 "v9, \"ip\"" $1 | tail -1 | cut -d'"' -f2` 5 | } 6 | 7 | get_packaged_date() { 8 | echo `unzip -v -l $1 | grep classes.dex | cut -d"%" -f2 | cut -d" " -f3` 9 | } 10 | 11 | for file in `find $1` 12 | do 13 | 14 | if [[ -f "$file" ]] && [[ "$file" == *.apk ]] 15 | then 16 | # Extract and decode assests 17 | java -jar ~/bin/apktool.jar -q d "$file" tmp/ 18 | 19 | # Search for files 20 | PACKAGE_NAME=`grep "package=" tmp/AndroidManifest.xml | sed 's/^.*package="//' | sed 's/".*//'` 21 | SHA1=`shasum "$file" | cut -c1-40` 22 | PACKAGED_DATE=`get_packaged_date $file` 23 | 24 | echo "Sha1: $SHA1" 25 | echo "Package Name: $PACKAGE_NAME" 26 | echo "Packaged Date: $PACKAGED_DATE" 27 | 28 | CONFIG="tmp/smali/my/app/client//ProcessCommand.smali" 29 | if [ ! -f $CONFIG ] 30 | then 31 | echo "Config not found in normal place!" 32 | fi 33 | 34 | if [ -f $CONFIG ] 35 | then 36 | #Un-encoded config values 37 | C2_URL=`get_normal_variable $CONFIG ">urlPostInfo"` 38 | 39 | # Pipe it all out 40 | echo "C2_URL: $C2_URL" 41 | echo "\n" 42 | else 43 | echo "No config file found!" 44 | fi 45 | # Clean up 46 | rm -rf tmp/ 47 | else 48 | echo "Skipping '$file'.." 49 | fi 50 | done -------------------------------------------------------------------------------- /Decoders/decode_kakabet.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | # 3 | # Copyright (C) 2013 Tim Strazzere - diff@lookout.com 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the 'License'); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an 'AS IS' BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | # 18 | # Decoder for Kakabet.a - targeted malware against Tibetian activists 19 | # Tested and used for sample; 20 | # SHA1: s495b622d8209820022fe743c340b39e6e9313cd9 21 | # SHA256: 9390a145806157cadc54ecd69d4ededc31534a19a1cebbb1824a9eb4febdc56d 22 | 23 | # Got to love the sense of humor and life advice... 24 | DECODE_KEY = "marriage and parenting are serious commitments dont be in a hurry" 25 | printf "[*] Kakabet decoder - Tim Strazzere - diff@lookout.com\n" 26 | 27 | if(ARGV.length != 1) 28 | printf " [!] Expecting one argument - exiting\n" 29 | exit 30 | end 31 | 32 | File.open(ARGV[0]) do |f| 33 | string = f.read 34 | 35 | # Kill the buffer in the front and back if it exists 36 | if(string.start_with?("<####") && string.end_with?("####>")) 37 | puts " [+] Padding found, removing...\n" 38 | string = string[5..string.length-5] 39 | end 40 | 41 | puts " [+] Using decode key: [ #{DECODE_KEY} ]\n" 42 | 43 | # Simple rotating xor 44 | output = "" 45 | offset = 0 46 | (0..string.length-1).each do |i| 47 | if(i % DECODE_KEY.length == 0) 48 | offset = 0 49 | end 50 | output << (string[i] ^ DECODE_KEY[offset]) 51 | offset += 1 52 | end 53 | puts " [*] Decoded output : \n#{output}\n" 54 | 55 | puts " [+] Attempting to parse..." 56 | config = output.split(/#### /) 57 | puts " [*] C2 [variable : ha] = #{config[1]}" 58 | puts " [*] FTP Server [variable : fa] = #{config[2]}" 59 | puts " [*] FTP Username [variable : fm] = #{config[3]}" 60 | puts " [*] FTP Password [variable : fp] = #{config[4]}" 61 | puts " [*] AlarmServiceini-timehour [variable : th] = #{config[5]}" 62 | puts " [*] AlarmServiceini-timeminute [variable : tm] = #{config[6]}" 63 | puts " [*] Unused [variable : bol] = #{config[7]}" 64 | puts " [*] Unused telephone numbers [variable : num] = #{config[8]}" 65 | end 66 | -------------------------------------------------------------------------------- /Decoders/dendroid/extract-config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Check for dependancy of base64 command 4 | command -v base64 >/dev/null 2>&1 || { 5 | echo >&2 "base64 is not available, aborting!" 6 | exit 1 7 | } 8 | 9 | decode_base64 () { 10 | echo "$1" | base64 -D ; echo 11 | } 12 | 13 | get_normal_variable() { 14 | echo `grep -B 2 "$2" $1 | head -1 | cut -d\" -f2` 15 | } 16 | 17 | get_encoded_variable() { 18 | decode_base64 `get_normal_variable $1 $2` 19 | } 20 | 21 | get_packaged_date() { 22 | echo `unzip -v -l $1 | grep classes.dex | cut -d"%" -f2 | cut -d" " -f3` 23 | } 24 | 25 | for file in `find $1` 26 | do 27 | 28 | if [[ -f "$file" ]] && [[ "$file" == *.apk ]] 29 | then 30 | # Extract and decode assests 31 | java -jar ~/bin/apktool.jar -q d "$file" tmp/ 32 | 33 | # Search for files 34 | PACKAGE_NAME=`grep "package=" tmp/AndroidManifest.xml | sed 's/^.*package="//' | sed 's/".*//'` 35 | SHA1=`shasum "$file" | cut -c1-40` 36 | PACKAGED_DATE=`get_packaged_date $file` 37 | 38 | echo "Sha1: $SHA1" 39 | echo "Package Name: $PACKAGE_NAME" 40 | echo "Packaged Date: $PACKAGED_DATE" 41 | 42 | CONFIG="tmp/smali/com/connect/MyService.smali" 43 | if [ ! -f $CONFIG ] 44 | then 45 | echo "Config not found in normal place!" 46 | fi 47 | 48 | if [ -f $CONFIG ] 49 | then 50 | #Un-encoded config values 51 | # GPLAY_BYPASS=`get_normal_variable $CONFIG ">GPlayBypass"` 52 | URL_POSTINFO=`get_normal_variable $CONFIG ">urlPostInfo"` 53 | if [ -z "$URL_POSTINFO" ] 54 | then 55 | URL_POSTINFO=`get_normal_variable $CONFIG ">ﹳ"` 56 | fi 57 | 58 | URL_SENDUPDATE=`get_normal_variable $CONFIG ">urlSendUpdate"` 59 | if [ -z "$URL_SENDUPDATE" ] 60 | then 61 | URL_SENDUPDATE=`get_normal_variable $CONFIG ">゙"` 62 | fi 63 | 64 | URL_UPLOADFILES=`get_normal_variable $CONFIG ">urlUploadFiles"` 65 | if [ -z "$URL_UPLOADFILES" ] 66 | then 67 | URL_UPLOADFILES=`get_normal_variable $CONFIG ">ʹ"` 68 | fi 69 | 70 | URL_UPLOADPICTURES=`get_normal_variable $CONFIG ">urlUploadPictures"` 71 | if [ -z "$URL_UPLOADPICTURES" ] 72 | then 73 | URL_UPLOADPICTURES=`get_normal_variable $CONFIG ">ՙ"` 74 | fi 75 | 76 | URL_FUNCTIONS=`get_normal_variable $CONFIG ">urlFunctions"` 77 | if [ -z "$URL_FUNCTIONS" ] 78 | then 79 | URL_FUNCTIONS=`get_normal_variable $CONFIG ">י"` 80 | fi 81 | 82 | # Encoded values we must decode 83 | ENCODED_URL=`get_encoded_variable $CONFIG ">encodedURL"` 84 | if [ -z "$ENCODED_URL" ] 85 | then 86 | ENCODED_URL=`get_encoded_variable $CONFIG ">ˎ"` 87 | fi 88 | BACKUP_URL=`get_encoded_variable $CONFIG ">backupURL"` 89 | if [ -z "$BACKUP_URL" ] 90 | then 91 | BACKUP_URL=`get_encoded_variable $CONFIG ">ˏ"` 92 | fi 93 | ENCODED_PASSWORD=`get_encoded_variable $CONFIG ">encodedPassword"` 94 | if [ -z "$ENCODED_PASSWORD" ] 95 | then 96 | ENCODED_PASSWORD=`get_encoded_variable $CONFIG ">ᐝ"` 97 | fi 98 | 99 | # Pipe it all out 100 | # echo "GPLAY_BYPASS: $GPLAY_BYPASS" 101 | echo "URL_POSTINFO: $URL_POSTINFO" 102 | echo "URL_SENDUPDATE: $URL_SENDUPDATE" 103 | echo "URL_UPLOADFILES: $URL_UPLOADFILES" 104 | echo "URL_UPLOADPICTURES: $URL_UPLOADPICTURES" 105 | echo "URL_FUNCTIONS: $URL_FUNCTIONS" 106 | 107 | echo "ENCODED_URL (c2): $ENCODED_URL" 108 | echo "BACKUP_URL: $BACKUP_URL" 109 | echo "ENCODED_PASSWORD: $ENCODED_PASSWORD" 110 | echo "\n" 111 | else 112 | echo "No config file found!" 113 | fi 114 | # Clean up 115 | rm -rf tmp/ 116 | else 117 | echo "Skipping '$file'.." 118 | fi 119 | done -------------------------------------------------------------------------------- /Decoders/imogui/imocrypto.java: -------------------------------------------------------------------------------- 1 | /** 2 | * "Encrypt" class from the imogui Android malware, 3 | * used to decrypt the aes encrypted strings 4 | * sent and received from C&Cs 5 | * 6 | * @author Tim "diff" Strazzere 7 | * 8 | * 9 | */ 10 | import javax.crypto.Cipher; 11 | import javax.crypto.spec.IvParameterSpec; 12 | import javax.crypto.spec.SecretKeySpec; 13 | 14 | import org.apache.commons.codec.binary.Base64; 15 | 16 | public class imocrypto { 17 | public static void main(String[] args) { 18 | 19 | if (args.length < 2) { 20 | System.err.println("Usage: imocrypto e[ncrypt]/d[ecrypt] "); 21 | return; 22 | } 23 | 24 | if (args[0].toLowerCase().startsWith("e")) { 25 | System.out.println(encrypt(args[1])); 26 | } else if (args[0].toLowerCase().startsWith("d")) { 27 | System.out.println(desEncrypt(args[1])); 28 | } else { 29 | System.err.println("Usage: imocrypto e[ncrypt]/d[ecrypt] "); 30 | return; 31 | } 32 | } 33 | 34 | // Take a minute to let it sink in... "base64", "desEncrypt", but it's decrypting and using AES... 35 | // public static java.lang.String com.android.base64.Encryption.desEncrypt(java.lang.String data) 36 | public static String desEncrypt(String data) { 37 | try { 38 | byte[] encrypted = Base64.decodeBase64(data); 39 | Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); 40 | SecretKeySpec keySpec = new SecretKeySpec("1234567812345678".getBytes(), "AES"); 41 | IvParameterSpec ivParameterSpec = new IvParameterSpec("1234567812345678".getBytes()); 42 | cipher.init(Cipher.DECRYPT_MODE, keySpec, ivParameterSpec); 43 | byte[] original = cipher.doFinal(encrypted); 44 | 45 | // Sloppy way to trip off excess data added for block ciphering 46 | int a = 0; 47 | for (int i = original.length - 1; i >= 0; i--) { 48 | if (original[i] == 0x00) { 49 | a++; 50 | } 51 | } 52 | 53 | byte[] ye = new byte[original.length - a]; 54 | 55 | System.arraycopy(original, 0, ye, 0, ye.length); 56 | 57 | return new String(ye, "UTF-8"); 58 | } catch (Exception e) { 59 | e.printStackTrace(); 60 | } 61 | 62 | return null; 63 | } 64 | 65 | public static String encrypt(String data) { 66 | try { 67 | // Use a million variables because they are insane 68 | Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); 69 | int blockSize = cipher.getBlockSize(); 70 | byte[] dataBytes = data.getBytes(); 71 | int plaintextLength = dataBytes.length; 72 | // Increase the size to fit blocksize o_O 73 | if ((plaintextLength % blockSize) != 0) { 74 | plaintextLength += blockSize - (plaintextLength % blockSize); 75 | } 76 | // Create a new array and copy the junk over (this ensures the remaining extra blocks are 0x00 77 | byte[] plaintext = new byte[plaintextLength]; 78 | System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length); 79 | // Crypto initialization w/ super secret keys/ivs 80 | SecretKeySpec keySpec = new SecretKeySpec("1234567812345678".getBytes(), "AES"); 81 | IvParameterSpec ivParameterSpec = new IvParameterSpec("1234567812345678".getBytes()); 82 | 83 | cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivParameterSpec); 84 | byte[] encrypted = cipher.doFinal(plaintext); 85 | 86 | return Base64.encodeBase64String(encrypted); 87 | } catch (Exception e) { 88 | // TODO Auto-generated catch block 89 | e.printStackTrace(); 90 | } 91 | return null; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /Decoders/rstealer/RazStealerDecrypter.1sc: -------------------------------------------------------------------------------- 1 | //-------------------------------------- 2 | //--- 010 Editor v5.0beta2 Script File 3 | // 4 | // File: RazStealerDecrypter.1sc 5 | // Author: Tim Strazzere 6 | // Revision: 1.0 7 | // Purpose: A quick script to decrypt RStealer.A/RazStealer 8 | // just as a test to see if it's worth while trying 9 | // to use 010Editor scripts for templates. 10 | // 11 | // Requires DEXTemplate.bt to be run first. 12 | //-------------------------------------- 13 | 14 | string decrypt(string data) { 15 | // Use temp variable so we don't kill the dex file string 16 | string temp = data; 17 | string output = ""; 18 | int last_underscore; 19 | if(Strstr(data, "_") == -1) 20 | return ""; 21 | 22 | while((last_underscore = Strstr(temp, "_")) != -1) { 23 | // Parse number 24 | if(Atoi(SubStr(temp, 0, last_underscore)) == 0) { 25 | return ""; 26 | } 27 | SPrintf(output, "%s%c", output, Sqrt(Atoi(SubStr(temp, 0, last_underscore)))); 28 | // Remove the chunk we just looked at 29 | temp = SubStr(temp, last_underscore + 1, -1); 30 | } 31 | 32 | // Encrypted strings should have no left over characters 33 | if(Strlen(temp) != 0) 34 | return ""; 35 | 36 | return output; 37 | } 38 | 39 | if(ReadUByte(0) != 0x64 && ReadUByte(1) != 0x65 && ReadUByte(2) != 0x78) { 40 | return "Doesn't appear to be a DEX file - quitting!\n"; 41 | }else if(!exists(dex_string_ids)) { 42 | return "DEXTemplate doesn't appear to have been run!"; 43 | } 44 | 45 | // Strings indexes must be sorted alphanumerical, so if we find 46 | // a grouping of encrypted strings we can stop once we detect a 47 | // non-encrypted string 48 | 49 | // Number of string indexes is dex_string_ids size / uint size 50 | int i, found_encrypted = 0; 51 | for(i = 0; i < sizeof(dex_string_ids)/4; i++) { 52 | if(decrypt(dex_string_ids.string_id[i].string_data.data) != "") { 53 | Printf("[ %s ] was decrypted from [ %s ]\n", decrypt(dex_string_ids.string_id[i].string_data.data), dex_string_ids.string_id[i].string_data.data); 54 | } else { 55 | if(found_encrypted) { 56 | break; 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /Decoders/rstealer/extract-config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ ! -f "razstealer_decoder.class" ] 4 | then 5 | javac razstealer_decoder.java 6 | fi 7 | 8 | for file in `find $1` 9 | do 10 | 11 | if [ -f "$file" ] 12 | then 13 | # Extract and decode assests 14 | java -jar ~/bin/apktool.jar -q d "$file" tmp/ 15 | 16 | # Search for files 17 | PACKAGE_NAME=`grep "package=" tmp/AndroidManifest.xml | sed 's/^.*package="//' | sed 's/".*//'` 18 | SHA1=`shasum "$file"` 19 | 20 | echo "Sha1: $SHA1" 21 | echo "Package Name: $PACKAGE_NAME" 22 | 23 | GLOBAL="tmp/smali/com/android/systemSettings/Globals.smali" 24 | if [ ! -f $GLOBAL ] 25 | then 26 | echo "Global config not found in normal place, attempt secondary location..." 27 | GLOBAL=`find tmp/ -name Globals.smali` 28 | fi 29 | 30 | DECODE="java razstealer_decoder" 31 | if [ -f $GLOBAL ] 32 | then 33 | #Un-encoded config values 34 | STEAL_CONTACTS=`grep -B 2 ">stealContacts" $GLOBAL | head -1 | cut -d\" -f2` 35 | STEAL_SMS=`grep -B 2 ">stealSMS" $GLOBAL | head -1 | cut -d\" -f2` 36 | STEAL_INFO=`grep -B 2 ">stealInfo" $GLOBAL | head -1 | cut -d\" -f2` 37 | STEAL_PICS=`grep -B 2 ">stealPics" $GLOBAL | head -1 | cut -d\" -f2` 38 | STEAL_WHATSAPP=`grep -B 2 ">stealWhatsapp" $GLOBAL | head -1 | cut -d\" -f2` 39 | USE_ROOT=`grep -B 2 ">useRoot" $GLOBAL | head -1 | cut -d\" -f2` 40 | ZIP_DATA=`grep -B 2 ">zipData" $GLOBAL | head -1 | cut -d\" -f2` 41 | DELETE_ZIP=`grep -B 2 ">deleteZip" $GLOBAL | head -1 | cut -d\" -f2` 42 | TRIGGER_VIA_SMS=`grep -B 2 ">triggerViaSms" $GLOBAL | head -1 | cut -d\" -f2` 43 | RUN_ON_STARTUP=`grep -B 2 ">runOnStartup" $GLOBAL | head -1 | cut -d\" -f2` 44 | MINUTE_OFFSET=`grep -B 2 ">minuteOffset" $GLOBAL | head -1 | cut -d\" -f2` 45 | USE_DATA=`grep -B 2 ">useData" $GLOBAL | head -1 | cut -d\" -f2` 46 | MAIL_PROVIDER=`grep -B 2 ">mailProvider" $GLOBAL | head -1 | sed "s/^.*>//" | cut -d: -f1` 47 | if [[ $MAIL_PROVIDER == *const-string* ]] 48 | then 49 | MAIL_PROVIDER=`echo $MAIL_PROVIDER | cut -d\" -f2` 50 | fi 51 | USE_FTP=`grep -B 2 ">useFTP" $GLOBAL | head -1 | cut -d\" -f2` 52 | 53 | # Encoded values we must decode 54 | TRIGGER_START=`grep -B 2 ">triggerStart" $GLOBAL | head -1 | cut -d\" -f2` 55 | TRIGGER_START=`$DECODE $TRIGGER_START` 56 | MY_MAIL=`grep -B 2 ">myMail" $GLOBAL | head -1 | cut -d\" -f2` 57 | MY_MAIL=`$DECODE $MY_MAIL` 58 | MY_PASSWORD=`grep -B 2 ">myPassword" $GLOBAL | head -1 | cut -d\" -f2` 59 | MY_PASSWORD=`$DECODE $MY_PASSWORD` 60 | YOUR_MAIL=`grep -B 2 ">yourMail" $GLOBAL | head -1 | cut -d\" -f2` 61 | YOUR_MAIL=`$DECODE $YOUR_MAIL` 62 | FTP_HOST=`grep -B 2 ">ftpHost" $GLOBAL | head -1 | cut -d\" -f2` 63 | FTP_HOST=`$DECODE $FTP_HOST` 64 | FTP_USER=`grep -B 2 ">ftpUser" $GLOBAL | head -1 | cut -d\" -f2` 65 | FTP_USER=`$DECODE $FTP_USER` 66 | FTP_PW=`grep -B 2 ">ftpPw" $GLOBAL | head -1 | cut -d\" -f2` 67 | FTP_PW=`$DECODE $FTP_PW` 68 | FTP_PORT=`grep -B 2 ">ftpPort" $GLOBAL | head -1 | cut -d\" -f2` 69 | FTP_PORT=`$DECODE $FTP_PORT` 70 | ANDROID_DATA_PATH=`grep -B 2 ">androidDataPath" $GLOBAL | head -1 | cut -d\" -f2` 71 | ANDROID_DATA_PATH=`$DECODE $ANDROID_DATA_PATH` 72 | 73 | # Pipe it all out 74 | echo "MY_MAIL: $MY_MAIL" 75 | echo "MY_PASSWORD: $MY_PASSWORD" 76 | echo "YOUR_MAIL: $YOUR_MAIL" 77 | echo "STEAL_CONTACTS: $STEAL_CONTACTS" 78 | echo "STEAL_SMS: $STEAL_SMS" 79 | echo "STEAL_INFO: $STEAL_INFO" 80 | echo "STEAL_PICS: $STEAL_PICS" 81 | echo "STEAL_WHATSAPP: $STEAL_WHATSAPP" 82 | echo "USE_ROOT: $USE_ROOT" 83 | echo "ZIP_DATA: $ZIP_DATA" 84 | echo "DELETE_ZIP: $DELETE_ZIP" 85 | echo "TRIGGER_START: $TRIGGER_START" 86 | if [[ -z "$TRIGGER_VIA_SMS" ]] 87 | then 88 | TRIGGER_VIA_SMS="Not found, likely version where always enabled" 89 | fi 90 | echo "TRIGGER_VIA_SMS: $TRIGGER_VIA_SMS" 91 | echo "RUN_ON_STARTUP: $RUN_ON_STARTUP" 92 | echo "MINUTE_OFFSET: $MINUTE_OFFSET" 93 | echo "USE_DATA: $USE_DATA" 94 | echo "MAIL_PROVIDER: $MAIL_PROVIDER" 95 | echo "USE_FTP: $USE_FTP" 96 | echo "FTP_HOST: $FTP_HOST" 97 | echo "FTP_USER: $FTP_USER" 98 | echo "FTP_PW: $FTP_PW" 99 | echo "FTP_PORT: $FTP_PORT" 100 | echo "ANDROID_DATA_PATH: $ANDROID_DATA_PATH" 101 | echo "\n" 102 | else 103 | echo "No config file found!" 104 | fi 105 | # Clean up 106 | rm -rf tmp/ 107 | else 108 | echo "File doesn't appear to be regular file, skipping.." 109 | fi 110 | done -------------------------------------------------------------------------------- /Decoders/rstealer/razstealer_decoder.java: -------------------------------------------------------------------------------- 1 | 2 | public class razstealer_decoder { 3 | 4 | public static void main(String[] args) { 5 | if(args.length < 1) 6 | System.out.println("Nothing to decode"); 7 | for(String to_decode : args) { 8 | System.out.println(decoder(to_decode)); 9 | } 10 | } 11 | 12 | public static String decoder(String data_to_decode) { 13 | StringBuffer output = new StringBuffer(); 14 | String[] splits = data_to_decode.split("_"); 15 | 16 | for(String data : splits) { 17 | output.append(String.valueOf((char)(byte)Math.sqrt(Integer.parseInt(data)))); 18 | } 19 | 20 | return output.toString(); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /Decoders/scaremenot.b/scaremenot_b_decode.java: -------------------------------------------------------------------------------- 1 | /** 2 | * "Decode" class from the ScareMeNot.b Android malware, 3 | * used for decoding the ransomwares C2 which is often 4 | * parse of a string array in the resources file 5 | * 6 | * @author Tim "diff" Strazzere 7 | * 8 | * 9 | */ 10 | 11 | import java.io.UnsupportedEncodingException; 12 | import org.apache.commons.codec.binary.Base64; 13 | 14 | public class scaremenot_b_decode { 15 | 16 | public static void main(String[] args) { 17 | try { 18 | if (args.length < 1) { 19 | System.err.print("Usage: decode "); 20 | return; 21 | } 22 | for (String arg : args) { 23 | System.out.println(arg + " -> " + decode(arg)); 24 | } 25 | } catch (Exception e) { 26 | e.printStackTrace(); 27 | } 28 | } 29 | 30 | // Silly modification to normal base64 decoding 31 | public static String decode(String data) throws UnsupportedEncodingException { 32 | StringBuffer buffer = new StringBuffer(data.length()); 33 | 34 | for (int i = 0; i < (data.length() / 2); i++) { 35 | buffer.append(data.charAt((i * 2) + 1)); 36 | buffer.append(data.charAt(i * 2)); 37 | } 38 | 39 | return new String(Base64.decodeBase64(buffer.toString()), "UTF-8"); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Decoders/simplocker.c/extract-data.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | get_c2_address() { 4 | echo `grep "\"http" $1 | cut -d\" -f2` 5 | } 6 | 7 | get_number_of_extort_numbers() { 8 | echo `grep -ir "\+" tmp/res/values/strings.xml | cut -d"+" -f2 | cut -d" " -f1 | wc -l | tr -d " "` 9 | } 10 | 11 | get_extort_number() { 12 | echo `grep -ir "\+" tmp/res/values/strings.xml | cut -d"+" -f2 | cut -d" " -f1 | sed -n $1p` 13 | } 14 | 15 | get_packaged_date() { 16 | echo `unzip -v -l $1 | grep classes.dex | cut -d"%" -f2 | cut -d" " -f3` 17 | } 18 | 19 | get_number_of_countries() { 20 | echo `grep -ir "getCountry" $1 | wc -l | tr -d " "` 21 | } 22 | 23 | get_country() { 24 | GET_COUNTRY_LINE=`grep -ir -nr "getCountry" $1 | sed -n $2p | cut -d":" -f2` 25 | 26 | echo `sed -n $(expr $GET_COUNTRY_LINE + 4)p $1 | cut -d"\"" -f2` 27 | } 28 | 29 | for file in `find $1` 30 | do 31 | 32 | if [[ -f "$file" ]] && [[ "$file" == *.apk ]] 33 | then 34 | # Extract and decode assests 35 | java -jar ~/bin/apktool.jar -q d "$file" tmp/ 36 | 37 | # Search for files 38 | PACKAGE_NAME=`grep "package=" tmp/AndroidManifest.xml | sed 's/^.*package="//' | sed 's/".*//'` 39 | SHA1=`shasum "$file" | cut -c1-40` 40 | PACKAGED_DATE=`get_packaged_date $file` 41 | 42 | echo "Sha1: $SHA1" 43 | echo "Package Name: $PACKAGE_NAME" 44 | echo "Packaged Date: $PACKAGED_DATE" 45 | 46 | C2="tmp/smali/my/sharaga/loser/f.smali" 47 | if [ -f $C2 ] 48 | then 49 | ADDRESS=`get_c2_address $C2` 50 | 51 | NUM_EXTORT=`get_number_of_extort_numbers` 52 | 53 | echo "C2 ADDRESS: $ADDRESS" 54 | echo "NUMBER OF EXTORTION #s: $NUM_EXTORT" 55 | 56 | for i in $(seq 1 $NUM_EXTORT) 57 | do 58 | CURRENT_EXTORT=`get_extort_number $i` 59 | echo "EXTORTION #$i: +$CURRENT_EXTORT" 60 | done 61 | else 62 | echo "No C2 file found!" 63 | fi 64 | 65 | COUNTRY="tmp/smali/my/sharaga/loser/Main.smali" 66 | if [ -f $COUNTRY ] 67 | then 68 | NUM_COUNTRIES=`get_number_of_countries $COUNTRY` 69 | echo "# OF COUNTRIES TARGETED: $NUM_COUNTRIES" 70 | 71 | for i in $(seq 1 $NUM_COUNTRIES) 72 | do 73 | CURRENT_COUNTRY=`get_country $COUNTRY $i` 74 | echo "COUNTRY CODE #$i: $CURRENT_COUNTRY" 75 | done 76 | else 77 | echo "No country config file found!" 78 | fi 79 | # Clean up 80 | rm -rf tmp/ 81 | else 82 | echo "Skipping '$file'.." 83 | fi 84 | done -------------------------------------------------------------------------------- /Decoders/simplocker.c/simplocker_gen.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Extract out the "gen" method and "rand" 3 | * functions pulled from Simplocker.c to 4 | * do some testing and see what was going on 5 | * in comparison to other randomware variants. 6 | * 7 | * Potentially some overlap with other malware. 8 | * 9 | * @author Tim "diff" Strazzere 10 | * 11 | * 12 | */ 13 | import java.util.Random; 14 | 15 | public class simplocker_gen { 16 | 17 | public static void main(String[] args) { 18 | System.out.println(genkey()); 19 | } 20 | 21 | public static int genkey() { 22 | int j = 1; 23 | int k = 9; 24 | for(int i = 0; i < 5; i++) { 25 | j *= 0xA; 26 | k = (k * 0xA) + 9; 27 | } 28 | 29 | return rnd(j, k); 30 | } 31 | 32 | public static int rnd(int i, int j) { 33 | return (Math.abs(new Random().nextInt()) % (i -j)) + i; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Decoders/simplocker.d/simplocker_d_decoder.java: -------------------------------------------------------------------------------- 1 | /** 2 | * "Decode" class from the simplocker.d Android malware, 3 | * lazily will try the two different keys I've seen 4 | * in the wild being used to try to decode the config. 5 | * 6 | * @author Tim "diff" Strazzere 7 | * 8 | * 9 | */ 10 | import java.net.URLDecoder; 11 | 12 | public class simplocker_d_decoder { 13 | 14 | public static void main(String[] args) { 15 | 16 | if (args.length < 1) { 17 | System.err.println("Usages: decode "); 18 | return; 19 | } 20 | 21 | for (String arg : args) { 22 | String[] config = decode(arg); 23 | 24 | if (config == null) { 25 | System.err.println("Error: likely an unknown xor key being used!"); 26 | return; 27 | } 28 | 29 | if (config.length != 5) { 30 | System.err.println("Warning: odd returned length of config!"); 31 | } 32 | 33 | System.out.println("C2: " + config[0]); 34 | System.out.println("Unused: " + config[1]); 35 | System.out.println("Client Number: " + config[2]); 36 | System.out.println("AES Encryption Key: " + config[3]); 37 | System.out.println("Extensions to encrypt: " + config[4]); 38 | System.out.println(""); 39 | } 40 | } 41 | 42 | public static String[] decode(String data) { 43 | String[] keys = { "chihanin", "ebcncjejane" }; 44 | for (String key : keys) { 45 | String[] attempt = decode(data, key); 46 | if (attempt.length == 5) { 47 | return attempt; 48 | } 49 | } 50 | 51 | return null; 52 | } 53 | 54 | @SuppressWarnings("deprecation") 55 | public static String[] decode(String data, String xor_key) { 56 | 57 | data = URLDecoder.decode(data); 58 | 59 | StringBuffer buffer = new StringBuffer(data); 60 | int x = 0; 61 | 62 | for (int i = 0; i < data.length(); i++) { 63 | if (x >= xor_key.length()) { 64 | x = 0; 65 | } 66 | buffer.setCharAt(i, (char) (data.charAt(i) ^ xor_key.charAt(x))); 67 | x++; 68 | } 69 | 70 | return buffer.toString().split(","); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Decoders/spyeye.a/spyeye_decode.java: -------------------------------------------------------------------------------- 1 | /** 2 | * "Decode" class from the SpyEye.a Android malware 3 | * 4 | * @author Tim "diff" Strazzere 5 | * 6 | * 7 | */ 8 | 9 | public class spyeye_decode { 10 | public static void main(String[] args) { 11 | if (args.length < 1) { 12 | System.err.print("Usage: decode "); 13 | return; 14 | } 15 | for (String arg : args) 16 | System.out.println(arg + " -> " + cleanData(arg)); 17 | } 18 | 19 | public static String cleanData(String data) { 20 | String[] removals = { "[", "]", "=", "-", "q", ",", "<", ">", "\'", ";", "%" }; 21 | 22 | for (String removal : removals) { 23 | data = data.replace(removal, ""); 24 | } 25 | 26 | return data; 27 | } 28 | } -------------------------------------------------------------------------------- /IDA/IDA_JNI_Rename/ReadMe.md: -------------------------------------------------------------------------------- 1 | # IDA JNI 2 | 3 | Really cool plugin from `trojancyborg` - used it for a long time but needed up today it for IDA 7.4+. 4 | 5 | Originally was at `https://github.com/trojancyborg/IDA_JNI_Rename` 6 | 7 | # IDA JNI调用重命名脚本 8 | >#### 使用说明: 9 | >先使用ida打开要分析的程序,等ida自动分析完成,使用ALT+F7,执行本脚本,本脚本会根据jni的调用的偏移值在ida中创建两个枚举类型,然后扫描用户的函数,根据汇编指令自动分析jni调用点,添加注释,如果遇到无法识别的指令,可以在**偏移**上面按m键手动设置。支持F5插件,如果未成功自动识别,请按m手动设置。 10 | > 11 | #### 运行脚本前 12 | ``` 13 | #.text:00005C0A E1 68 LDR R1, [R4,#(dword_1626C - 0x16260)] 14 | #.text:00005C0C 9B 69 LDR R3, [R3,#0x18] 15 | #.text:00005C0E 98 47 BLX R3 16 | ``` 17 | #### 运行脚本后 18 | ``` 19 | #.text:00005C0A E1 68 LDR R1, [R4,#(dword_1626C - 0x16260)] 20 | #.text:00005C0C 9B 69 LDR R3, [R3,#jni_FindClass] ; jclass FindClass (JNIEnv*, const char*); 21 | #.text:00005C0E 98 47 BLX R3 22 | ``` 23 | 24 | 25 | -------------------------------------------------------------------------------- /IDA/IDA_JNI_Rename/ida_jni.py: -------------------------------------------------------------------------------- 1 | #coding=UTF8 2 | # 2014/09/05 11:51 3 | # by trojancyborg 4 | # ida jni调用自动重命名脚本 5 | #例: 6 | # 7 | #.text:00005C0A E1 68 LDR R1, [R4,#(dword_1626C - 0x16260)] 8 | #.text:00005C0C 9B 69 LDR R3, [R3,#0x18] 9 | #.text:00005C0E 98 47 BLX R3 10 | # 11 | #.text:00005C0A E1 68 LDR R1, [R4,#(dword_1626C - 0x16260)] 12 | #.text:00005C0C 9B 69 LDR R3, [R3,#jni_FindClass] ; jclass FindClass (JNIEnv*, const char*); 13 | #.text:00005C0E 98 47 BLX R3 14 | # 15 | 16 | from idautils import * 17 | 18 | #枚举名 19 | Enum_JNI_Name = "JNI_Interface" 20 | 21 | #通用寄存器 22 | COMMON_REG = ['R%d' % i for i in range(0,13)] 23 | 24 | #引用类型----------------------- 25 | #立即数字 26 | OP_Immediate = 5 27 | 28 | #EXP: LDR R3,[R3,#0x10] 29 | OP_Base_Index_Displacement = 4 30 | 31 | #EXP: LDR R3,[R1,R2] 32 | OP_Base_Index = 3 33 | 34 | #------------------------------- 35 | 36 | 37 | 38 | jni_names_list = [ 39 | "jni_GetVersion", 40 | "jni_DefineClass", 41 | "jni_FindClass", 42 | "jni_FromReflectedMethod", 43 | "jni_FromReflectedField", 44 | "jni_ToReflectedMethod", 45 | "jni_GetSuperclass", 46 | "jni_IsAssignableFrom", 47 | "jni_ToReflectedField", 48 | "jni_Throw", 49 | "jni_ThrowNew", 50 | "jni_ExceptionOccurred", 51 | "jni_ExceptionDescribe", 52 | "jni_ExceptionClear", 53 | "jni_FatalError", 54 | "jni_PushLocalFrame", 55 | "jni_PopLocalFrame", 56 | "jni_NewGlobalRef", 57 | "jni_DeleteGlobalRef", 58 | "jni_DeleteLocalRef", 59 | "jni_IsSameObject", 60 | "jni_NewLocalRef", 61 | "jni_EnsureLocalCapacity", 62 | "jni_AllocObject", 63 | "jni_NewObject", 64 | "jni_NewObjectV", 65 | "jni_NewObjectA", 66 | "jni_GetObjectClass", 67 | "jni_IsInstanceOf", 68 | "jni_GetMethodID", 69 | "jni_CallObjectMethod", 70 | "jni_CallObjectMethodV", 71 | "jni_CallObjectMethodA", 72 | "jni_CallBooleanMethod", 73 | "jni_CallBooleanMethodV", 74 | "jni_CallBooleanMethodA", 75 | "jni_CallByteMethod", 76 | "jni_CallByteMethodV", 77 | "jni_CallByteMethodA", 78 | "jni_CallCharMethod", 79 | "jni_CallCharMethodV", 80 | "jni_CallCharMethodA", 81 | "jni_CallShortMethod", 82 | "jni_CallShortMethodV", 83 | "jni_CallShortMethodA", 84 | "jni_CallIntMethod", 85 | "jni_CallIntMethodV", 86 | "jni_CallIntMethodA", 87 | "jni_CallLongMethod", 88 | "jni_CallLongMethodV", 89 | "jni_CallLongMethodA", 90 | "jni_CallFloatMethod", 91 | "jni_CallFloatMethodV", 92 | "jni_CallFloatMethodA", 93 | "jni_CallDoubleMethod", 94 | "jni_CallDoubleMethodV", 95 | "jni_CallDoubleMethodA", 96 | "jni_CallVoidMethod", 97 | "jni_CallVoidMethodV", 98 | "jni_CallVoidMethodA", 99 | "jni_CallNonvirtualObjectMethod", 100 | "jni_CallNonvirtualObjectMethodV", 101 | "jni_CallNonvirtualObjectMethodA", 102 | "jni_CallNonvirtualBooleanMethod", 103 | "jni_CallNonvirtualBooleanMethodV", 104 | "jni_CallNonvirtualBooleanMethodA", 105 | "jni_CallNonvirtualByteMethod", 106 | "jni_CallNonvirtualByteMethodV", 107 | "jni_CallNonvirtualByteMethodA", 108 | "jni_CallNonvirtualCharMethod", 109 | "jni_CallNonvirtualCharMethodV", 110 | "jni_CallNonvirtualCharMethodA", 111 | "jni_CallNonvirtualShortMethod", 112 | "jni_CallNonvirtualShortMethodV", 113 | "jni_CallNonvirtualShortMethodA", 114 | "jni_CallNonvirtualIntMethod", 115 | "jni_CallNonvirtualIntMethodV", 116 | "jni_CallNonvirtualIntMethodA", 117 | "jni_CallNonvirtualLongMethod", 118 | "jni_CallNonvirtualLongMethodV", 119 | "jni_CallNonvirtualLongMethodA", 120 | "jni_CallNonvirtualFloatMethod", 121 | "jni_CallNonvirtualFloatMethodV", 122 | "jni_CallNonvirtualFloatMethodA", 123 | "jni_CallNonvirtualDoubleMethod", 124 | "jni_CallNonvirtualDoubleMethodV", 125 | "jni_CallNonvirtualDoubleMethodA", 126 | "jni_CallNonvirtualVoidMethod", 127 | "jni_CallNonvirtualVoidMethodV", 128 | "jni_CallNonvirtualVoidMethodA", 129 | "jni_GetFieldID", 130 | "jni_GetObjectField", 131 | "jni_GetBooleanField", 132 | "jni_GetByteField", 133 | "jni_GetCharField", 134 | "jni_GetShortField", 135 | "jni_GetIntField", 136 | "jni_GetLongField", 137 | "jni_GetFloatField", 138 | "jni_GetDoubleField", 139 | "jni_SetObjectField", 140 | "jni_SetBooleanField", 141 | "jni_SetByteField", 142 | "jni_SetCharField", 143 | "jni_SetShortField", 144 | "jni_SetIntField", 145 | "jni_SetLongField", 146 | "jni_SetFloatField", 147 | "jni_SetDoubleField", 148 | "jni_GetStaticMethodID", 149 | "jni_CallStaticObjectMethod", 150 | "jni_CallStaticObjectMethodV", 151 | "jni_CallStaticObjectMethodA", 152 | "jni_CallStaticBooleanMethod", 153 | "jni_CallStaticBooleanMethodV", 154 | "jni_CallStaticBooleanMethodA", 155 | "jni_CallStaticByteMethod", 156 | "jni_CallStaticByteMethodV", 157 | "jni_CallStaticByteMethodA", 158 | "jni_CallStaticCharMethod", 159 | "jni_CallStaticCharMethodV", 160 | "jni_CallStaticCharMethodA", 161 | "jni_CallStaticShortMethod", 162 | "jni_CallStaticShortMethodV", 163 | "jni_CallStaticShortMethodA", 164 | "jni_CallStaticIntMethod", 165 | "jni_CallStaticIntMethodV", 166 | "jni_CallStaticIntMethodA", 167 | "jni_CallStaticLongMethod", 168 | "jni_CallStaticLongMethodV", 169 | "jni_CallStaticLongMethodA", 170 | "jni_CallStaticFloatMethod", 171 | "jni_CallStaticFloatMethodV", 172 | "jni_CallStaticFloatMethodA", 173 | "jni_CallStaticDoubleMethod", 174 | "jni_CallStaticDoubleMethodV", 175 | "jni_CallStaticDoubleMethodA", 176 | "jni_CallStaticVoidMethod", 177 | "jni_CallStaticVoidMethodV", 178 | "jni_CallStaticVoidMethodA", 179 | "jni_GetStaticFieldID", 180 | "jni_GetStaticObjectField", 181 | "jni_GetStaticBooleanField", 182 | "jni_GetStaticByteField", 183 | "jni_GetStaticCharField", 184 | "jni_GetStaticShortField", 185 | "jni_GetStaticIntField", 186 | "jni_GetStaticLongField", 187 | "jni_GetStaticFloatField", 188 | "jni_GetStaticDoubleField", 189 | "jni_SetStaticObjectField", 190 | "jni_SetStaticBooleanField", 191 | "jni_SetStaticByteField", 192 | "jni_SetStaticCharField", 193 | "jni_SetStaticShortField", 194 | "jni_SetStaticIntField", 195 | "jni_SetStaticLongField", 196 | "jni_SetStaticFloatField", 197 | "jni_SetStaticDoubleField", 198 | "jni_NewString", 199 | "jni_GetStringLength", 200 | "jni_GetStringChars", 201 | "jni_ReleaseStringChars", 202 | "jni_NewStringUTF", 203 | "jni_GetStringUTFLength", 204 | "jni_GetStringUTFChars", 205 | "jni_ReleaseStringUTFChars", 206 | "jni_GetArrayLength", 207 | "jni_NewObjectArray", 208 | "jni_GetObjectArrayElement", 209 | "jni_SetObjectArrayElement", 210 | "jni_NewBooleanArray", 211 | "jni_NewByteArray", 212 | "jni_NewCharArray", 213 | "jni_NewShortArray", 214 | "jni_NewIntArray", 215 | "jni_NewLongArray", 216 | "jni_NewFloatArray", 217 | "jni_NewDoubleArray", 218 | "jni_GetBooleanArrayElements", 219 | "jni_GetByteArrayElements", 220 | "jni_GetCharArrayElements", 221 | "jni_GetShortArrayElements", 222 | "jni_GetIntArrayElements", 223 | "jni_GetLongArrayElements", 224 | "jni_GetFloatArrayElements", 225 | "jni_GetDoubleArrayElements", 226 | "jni_ReleaseBooleanArrayElements", 227 | "jni_ReleaseByteArrayElements", 228 | "jni_ReleaseCharArrayElements", 229 | "jni_ReleaseShortArrayElements", 230 | "jni_ReleaseIntArrayElements", 231 | "jni_ReleaseLongArrayElements", 232 | "jni_ReleaseFloatArrayElements", 233 | "jni_ReleaseDoubleArrayElements", 234 | "jni_GetBooleanArrayRegion", 235 | "jni_GetByteArrayRegion", 236 | "jni_GetCharArrayRegion", 237 | "jni_GetShortArrayRegion", 238 | "jni_GetIntArrayRegion", 239 | "jni_GetLongArrayRegion", 240 | "jni_GetFloatArrayRegion", 241 | "jni_GetDoubleArrayRegion", 242 | "jni_SetBooleanArrayRegion", 243 | "jni_SetByteArrayRegion", 244 | "jni_SetCharArrayRegion", 245 | "jni_SetShortArrayRegion", 246 | "jni_SetIntArrayRegion", 247 | "jni_SetLongArrayRegion", 248 | "jni_SetFloatArrayRegion", 249 | "jni_SetDoubleArrayRegion", 250 | "jni_RegisterNatives", 251 | "jni_UnregisterNatives", 252 | "jni_MonitorEnter", 253 | "jni_MonitorExit", 254 | "jni_GetJavaVM", 255 | "jni_GetStringRegion", 256 | "jni_GetStringUTFRegion", 257 | "jni_GetPrimitiveArrayCritical", 258 | "jni_ReleasePrimitiveArrayCritical", 259 | "jni_GetStringCritical", 260 | "jni_ReleaseStringCritical", 261 | "jni_NewWeakGlobalRef", 262 | "jni_DeleteWeakGlobalRef", 263 | "jni_ExceptionCheck", 264 | "jni_NewDirectByteBuffer", 265 | "jni_GetDirectBufferAddress", 266 | "jni_GetDirectBufferCapacity", 267 | "jni_GetObjectRefType" ] 268 | 269 | 270 | JNINativeInterface = [ 271 | r"void* reserved0;", 272 | r"void* reserved1;", 273 | r"void* reserved2;", 274 | r"void* reserved3;", 275 | r"jint GetVersion (JNIEnv *);", 276 | r"jclass DefineClass (JNIEnv*, const char*, jobject, const jbyte*, jsize);", 277 | r"jclass FindClass (JNIEnv*, const char*);", 278 | r"jmethodID FromReflectedMethod (JNIEnv*, jobject);", 279 | r"jfieldID FromReflectedField (JNIEnv*, jobject);", 280 | r"jobject ToReflectedMethod (JNIEnv*, jclass, jmethodID, jboolean);", 281 | r"jclass GetSuperclass (JNIEnv*, jclass);", 282 | r"jboolean IsAssignableFrom (JNIEnv*, jclass, jclass);", 283 | r"jobject ToReflectedField (JNIEnv*, jclass, jfieldID, jboolean);", 284 | r"jint Throw (JNIEnv*, jthrowable);", 285 | r"jint ThrowNew (JNIEnv *, jclass, const char *);", 286 | r"jthrowable ExceptionOccurred (JNIEnv*);", 287 | r"void ExceptionDescribe (JNIEnv*);", 288 | r"void ExceptionClear (JNIEnv*);", 289 | r"void FatalError (JNIEnv*, const char*);", 290 | r"jint PushLocalFrame (JNIEnv*, jint);", 291 | r"jobject PopLocalFrame (JNIEnv*, jobject);", 292 | r"jobject NewGlobalRef (JNIEnv*, jobject);", 293 | r"void DeleteGlobalRef (JNIEnv*, jobject);", 294 | r"void DeleteLocalRef (JNIEnv*, jobject);", 295 | r"jboolean IsSameObject (JNIEnv*, jobject, jobject);", 296 | r"jobject NewLocalRef (JNIEnv*, jobject);", 297 | r"jint EnsureLocalCapacity (JNIEnv*, jint);", 298 | r"jobject AllocObject (JNIEnv*, jclass);", 299 | r"jobject NewObject (JNIEnv*, jclass, jmethodID, ...);", 300 | r"jobject NewObjectV (JNIEnv*, jclass, jmethodID, va_list);", 301 | r"jobject NewObjectA (JNIEnv*, jclass, jmethodID, jvalue*);", 302 | r"jclass GetObjectClass (JNIEnv*, jobject);", 303 | r"jboolean IsInstanceOf (JNIEnv*, jobject, jclass);", 304 | r"jmethodID GetMethodID (JNIEnv*, jclass, const char*, const char*);", 305 | r"jobject CallObjectMethod (JNIEnv*, jobject, jmethodID, ...);", 306 | r"jobject CallObjectMethodV (JNIEnv*, jobject, jmethodID, va_list);", 307 | r"jobject CallObjectMethodA (JNIEnv*, jobject, jmethodID, jvalue*);", 308 | r"jboolean CallBooleanMethod (JNIEnv*, jobject, jmethodID, ...);", 309 | r"jboolean CallBooleanMethodV (JNIEnv*, jobject, jmethodID, va_list);", 310 | r"jboolean CallBooleanMethodA (JNIEnv*, jobject, jmethodID, jvalue*);", 311 | r"jbyte CallByteMethod (JNIEnv*, jobject, jmethodID, ...);", 312 | r"jbyte CallByteMethodV (JNIEnv*, jobject, jmethodID, va_list);", 313 | r"jbyte CallByteMethodA (JNIEnv*, jobject, jmethodID, jvalue*);", 314 | r"jchar CallCharMethod (JNIEnv*, jobject, jmethodID, ...);", 315 | r"jchar CallCharMethodV (JNIEnv*, jobject, jmethodID, va_list);", 316 | r"jchar CallCharMethodA (JNIEnv*, jobject, jmethodID, jvalue*);", 317 | r"jshort CallShortMethod (JNIEnv*, jobject, jmethodID, ...);", 318 | r"jshort CallShortMethodV (JNIEnv*, jobject, jmethodID, va_list);", 319 | r"jshort CallShortMethodA (JNIEnv*, jobject, jmethodID, jvalue*);", 320 | r"jint CallIntMethod (JNIEnv*, jobject, jmethodID, ...);", 321 | r"jint CallIntMethodV (JNIEnv*, jobject, jmethodID, va_list);", 322 | r"jint CallIntMethodA (JNIEnv*, jobject, jmethodID, jvalue*);", 323 | r"jlong CallLongMethod (JNIEnv*, jobject, jmethodID, ...);", 324 | r"jlong CallLongMethodV (JNIEnv*, jobject, jmethodID, va_list);", 325 | r"jlong CallLongMethodA (JNIEnv*, jobject, jmethodID, jvalue*);", 326 | r"jfloat CallFloatMethod (JNIEnv*, jobject, jmethodID, ...) __NDK_FPABI__;", 327 | r"jfloat CallFloatMethodV (JNIEnv*, jobject, jmethodID, va_list) __NDK_FPABI__;", 328 | r"jfloat CallFloatMethodA (JNIEnv*, jobject, jmethodID, jvalue*) __NDK_FPABI__;", 329 | r"jdouble CallDoubleMethod (JNIEnv*, jobject, jmethodID, ...) __NDK_FPABI__;", 330 | r"jdouble CallDoubleMethodV (JNIEnv*, jobject, jmethodID, va_list) __NDK_FPABI__;", 331 | r"jdouble CallDoubleMethodA (JNIEnv*, jobject, jmethodID, jvalue*) __NDK_FPABI__;", 332 | r"void CallVoidMethod (JNIEnv*, jobject, jmethodID, ...);", 333 | r"void CallVoidMethodV (JNIEnv*, jobject, jmethodID, va_list);", 334 | r"void CallVoidMethodA (JNIEnv*, jobject, jmethodID, jvalue*);", 335 | r"jobject CallNonvirtualObjectMethod (JNIEnv*, jobject, jclass, jmethodID, ...);", 336 | r"jobject CallNonvirtualObjectMethodV (JNIEnv*, jobject, jclass, jmethodID, va_list);", 337 | r"jobject CallNonvirtualObjectMethodA (JNIEnv*, jobject, jclass, jmethodID, jvalue*);", 338 | r"jboolean CallNonvirtualBooleanMethod (JNIEnv*, jobject, jclass, jmethodID, ...);", 339 | r"jboolean CallNonvirtualBooleanMethodV (JNIEnv*, jobject, jclass, jmethodID, va_list);", 340 | r"jboolean CallNonvirtualBooleanMethodA (JNIEnv*, jobject, jclass, jmethodID, jvalue*);", 341 | r"jbyte CallNonvirtualByteMethod (JNIEnv*, jobject, jclass, jmethodID, ...);", 342 | r"jbyte CallNonvirtualByteMethodV (JNIEnv*, jobject, jclass, jmethodID, va_list);", 343 | r"jbyte CallNonvirtualByteMethodA (JNIEnv*, jobject, jclass, jmethodID, jvalue*);", 344 | r"jchar CallNonvirtualCharMethod (JNIEnv*, jobject, jclass, jmethodID, ...);", 345 | r"jchar CallNonvirtualCharMethodV (JNIEnv*, jobject, jclass, jmethodID, va_list);", 346 | r"jchar CallNonvirtualCharMethodA (JNIEnv*, jobject, jclass, jmethodID, jvalue*);", 347 | r"jshort CallNonvirtualShortMethod (JNIEnv*, jobject, jclass, jmethodID, ...);", 348 | r"jshort CallNonvirtualShortMethodV (JNIEnv*, jobject, jclass, jmethodID, va_list);", 349 | r"jshort CallNonvirtualShortMethodA (JNIEnv*, jobject, jclass, jmethodID, jvalue*);", 350 | r"jint CallNonvirtualIntMethod (JNIEnv*, jobject, jclass, jmethodID, ...);", 351 | r"jint CallNonvirtualIntMethodV (JNIEnv*, jobject, jclass, jmethodID, va_list);", 352 | r"jint CallNonvirtualIntMethodA (JNIEnv*, jobject, jclass, jmethodID, jvalue*);", 353 | r"jlong CallNonvirtualLongMethod (JNIEnv*, jobject, jclass, jmethodID, ...);", 354 | r"jlong CallNonvirtualLongMethodV (JNIEnv*, jobject, jclass, jmethodID, va_list);", 355 | r"jlong CallNonvirtualLongMethodA (JNIEnv*, jobject, jclass, jmethodID, jvalue*);", 356 | r"jfloat CallNonvirtualFloatMethod (JNIEnv*, jobject, jclass, jmethodID, ...) __NDK_FPABI__;", 357 | r"jfloat CallNonvirtualFloatMethodV (JNIEnv*, jobject, jclass, jmethodID, va_list) __NDK_FPABI__;", 358 | r"jfloat CallNonvirtualFloatMethodA (JNIEnv*, jobject, jclass, jmethodID, jvalue*) __NDK_FPABI__;", 359 | r"jdouble CallNonvirtualDoubleMethod (JNIEnv*, jobject, jclass, jmethodID, ...) __NDK_FPABI__;", 360 | r"jdouble CallNonvirtualDoubleMethodV (JNIEnv*, jobject, jclass, jmethodID, va_list) __NDK_FPABI__;", 361 | r"jdouble CallNonvirtualDoubleMethodA (JNIEnv*, jobject, jclass, jmethodID, jvalue*) __NDK_FPABI__;", 362 | r"void CallNonvirtualVoidMethod (JNIEnv*, jobject, jclass, jmethodID, ...);", 363 | r"void CallNonvirtualVoidMethodV (JNIEnv*, jobject, jclass, jmethodID, va_list);", 364 | r"void CallNonvirtualVoidMethodA (JNIEnv*, jobject, jclass, jmethodID, jvalue*);", 365 | r"jfieldID GetFieldID (JNIEnv*, jclass, const char*, const char*);", 366 | r"jobject GetObjectField (JNIEnv*, jobject, jfieldID);", 367 | r"jboolean GetBooleanField (JNIEnv*, jobject, jfieldID);", 368 | r"jbyte GetByteField (JNIEnv*, jobject, jfieldID);", 369 | r"jchar GetCharField (JNIEnv*, jobject, jfieldID);", 370 | r"jshort GetShortField (JNIEnv*, jobject, jfieldID);", 371 | r"jint GetIntField (JNIEnv*, jobject, jfieldID);", 372 | r"jlong GetLongField (JNIEnv*, jobject, jfieldID);", 373 | r"jfloat GetFloatField (JNIEnv*, jobject, jfieldID) __NDK_FPABI__;", 374 | r"jdouble GetDoubleField (JNIEnv*, jobject, jfieldID) __NDK_FPABI__;", 375 | r"void SetObjectField (JNIEnv*, jobject, jfieldID, jobject);", 376 | r"void SetBooleanField (JNIEnv*, jobject, jfieldID, jboolean);", 377 | r"void SetByteField (JNIEnv*, jobject, jfieldID, jbyte);", 378 | r"void SetCharField (JNIEnv*, jobject, jfieldID, jchar);", 379 | r"void SetShortField (JNIEnv*, jobject, jfieldID, jshort);", 380 | r"void SetIntField (JNIEnv*, jobject, jfieldID, jint);", 381 | r"void SetLongField (JNIEnv*, jobject, jfieldID, jlong);", 382 | r"void SetFloatField (JNIEnv*, jobject, jfieldID, jfloat) __NDK_FPABI__;", 383 | r"void SetDoubleField (JNIEnv*, jobject, jfieldID, jdouble) __NDK_FPABI__;", 384 | r"jmethodID GetStaticMethodID (JNIEnv*, jclass, const char*, const char*);", 385 | r"jobject CallStaticObjectMethod (JNIEnv*, jclass, jmethodID, ...);", 386 | r"jobject CallStaticObjectMethodV (JNIEnv*, jclass, jmethodID, va_list);", 387 | r"jobject CallStaticObjectMethodA (JNIEnv*, jclass, jmethodID, jvalue*);", 388 | r"jboolean CallStaticBooleanMethod (JNIEnv*, jclass, jmethodID, ...);", 389 | r"jboolean CallStaticBooleanMethodV (JNIEnv*, jclass, jmethodID, va_list);", 390 | r"jboolean CallStaticBooleanMethodA (JNIEnv*, jclass, jmethodID, jvalue*);", 391 | r"jbyte CallStaticByteMethod (JNIEnv*, jclass, jmethodID, ...);", 392 | r"jbyte CallStaticByteMethodV (JNIEnv*, jclass, jmethodID, va_list);", 393 | r"jbyte CallStaticByteMethodA (JNIEnv*, jclass, jmethodID, jvalue*);", 394 | r"jchar CallStaticCharMethod (JNIEnv*, jclass, jmethodID, ...);", 395 | r"jchar CallStaticCharMethodV (JNIEnv*, jclass, jmethodID, va_list);", 396 | r"jchar CallStaticCharMethodA (JNIEnv*, jclass, jmethodID, jvalue*);", 397 | r"jshort CallStaticShortMethod (JNIEnv*, jclass, jmethodID, ...);", 398 | r"jshort CallStaticShortMethodV (JNIEnv*, jclass, jmethodID, va_list);", 399 | r"jshort CallStaticShortMethodA (JNIEnv*, jclass, jmethodID, jvalue*);", 400 | r"jint CallStaticIntMethod (JNIEnv*, jclass, jmethodID, ...);", 401 | r"jint CallStaticIntMethodV (JNIEnv*, jclass, jmethodID, va_list);", 402 | r"jint CallStaticIntMethodA (JNIEnv*, jclass, jmethodID, jvalue*);", 403 | r"jlong CallStaticLongMethod (JNIEnv*, jclass, jmethodID, ...);", 404 | r"jlong CallStaticLongMethodV (JNIEnv*, jclass, jmethodID, va_list);", 405 | r"jlong CallStaticLongMethodA (JNIEnv*, jclass, jmethodID, jvalue*);", 406 | r"jfloat CallStaticFloatMethod (JNIEnv*, jclass, jmethodID, ...) __NDK_FPABI__;", 407 | r"jfloat CallStaticFloatMethodV (JNIEnv*, jclass, jmethodID, va_list) __NDK_FPABI__;", 408 | r"jfloat CallStaticFloatMethodA (JNIEnv*, jclass, jmethodID, jvalue*) __NDK_FPABI__;", 409 | r"jdouble CallStaticDoubleMethod (JNIEnv*, jclass, jmethodID, ...) __NDK_FPABI__;", 410 | r"jdouble CallStaticDoubleMethodV (JNIEnv*, jclass, jmethodID, va_list) __NDK_FPABI__;", 411 | r"jdouble CallStaticDoubleMethodA (JNIEnv*, jclass, jmethodID, jvalue*) __NDK_FPABI__;", 412 | r"void CallStaticVoidMethod (JNIEnv*, jclass, jmethodID, ...);", 413 | r"void CallStaticVoidMethodV (JNIEnv*, jclass, jmethodID, va_list);", 414 | r"void CallStaticVoidMethodA (JNIEnv*, jclass, jmethodID, jvalue*);", 415 | r"jfieldID GetStaticFieldID (JNIEnv*, jclass, const char*, const char*);", 416 | r"jobject GetStaticObjectField (JNIEnv*, jclass, jfieldID);", 417 | r"jboolean GetStaticBooleanField (JNIEnv*, jclass, jfieldID);", 418 | r"jbyte GetStaticByteField (JNIEnv*, jclass, jfieldID);", 419 | r"jchar GetStaticCharField (JNIEnv*, jclass, jfieldID);", 420 | r"jshort GetStaticShortField (JNIEnv*, jclass, jfieldID);", 421 | r"jint GetStaticIntField (JNIEnv*, jclass, jfieldID);", 422 | r"jlong GetStaticLongField (JNIEnv*, jclass, jfieldID);", 423 | r"jfloat GetStaticFloatField (JNIEnv*, jclass, jfieldID) __NDK_FPABI__;", 424 | r"jdouble GetStaticDoubleField (JNIEnv*, jclass, jfieldID) __NDK_FPABI__;", 425 | r"void SetStaticObjectField (JNIEnv*, jclass, jfieldID, jobject);", 426 | r"void SetStaticBooleanField (JNIEnv*, jclass, jfieldID, jboolean);", 427 | r"void SetStaticByteField (JNIEnv*, jclass, jfieldID, jbyte);", 428 | r"void SetStaticCharField (JNIEnv*, jclass, jfieldID, jchar);", 429 | r"void SetStaticShortField (JNIEnv*, jclass, jfieldID, jshort);", 430 | r"void SetStaticIntField (JNIEnv*, jclass, jfieldID, jint);", 431 | r"void SetStaticLongField (JNIEnv*, jclass, jfieldID, jlong);", 432 | r"void SetStaticFloatField (JNIEnv*, jclass, jfieldID, jfloat) __NDK_FPABI__;", 433 | r"void SetStaticDoubleField (JNIEnv*, jclass, jfieldID, jdouble) __NDK_FPABI__;", 434 | r"jstring NewString (JNIEnv*, const jchar*, jsize);", 435 | r"jsize GetStringLength (JNIEnv*, jstring);", 436 | r"const jchar* GetStringChars (JNIEnv*, jstring, jboolean*);", 437 | r"void ReleaseStringChars (JNIEnv*, jstring, const jchar*);", 438 | r"jstring NewStringUTF (JNIEnv*, const char*);", 439 | r"jsize GetStringUTFLength (JNIEnv*, jstring);", 440 | r"const char* GetStringUTFChars (JNIEnv*, jstring, jboolean*);", 441 | r"void ReleaseStringUTFChars (JNIEnv*, jstring, const char*);", 442 | r"jsize GetArrayLength (JNIEnv*, jarray);", 443 | r"jobjectArray NewObjectArray (JNIEnv*, jsize, jclass, jobject);", 444 | r"jobject GetObjectArrayElement (JNIEnv*, jobjectArray, jsize);", 445 | r"void SetObjectArrayElement (JNIEnv*, jobjectArray, jsize, jobject);", 446 | r"jbooleanArray NewBooleanArray (JNIEnv*, jsize);", 447 | r"jbyteArray NewByteArray (JNIEnv*, jsize);", 448 | r"jcharArray NewCharArray (JNIEnv*, jsize);", 449 | r"jshortArray NewShortArray (JNIEnv*, jsize);", 450 | r"jintArray NewIntArray (JNIEnv*, jsize);", 451 | r"jlongArray NewLongArray (JNIEnv*, jsize);", 452 | r"jfloatArray NewFloatArray (JNIEnv*, jsize);", 453 | r"jdoubleArray NewDoubleArray (JNIEnv*, jsize);", 454 | r"jboolean* GetBooleanArrayElements (JNIEnv*, jbooleanArray, jboolean*);", 455 | r"jbyte* GetByteArrayElements (JNIEnv*, jbyteArray, jboolean*);", 456 | r"jchar* GetCharArrayElements (JNIEnv*, jcharArray, jboolean*);", 457 | r"jshort* GetShortArrayElements (JNIEnv*, jshortArray, jboolean*);", 458 | r"jint* GetIntArrayElements (JNIEnv*, jintArray, jboolean*);", 459 | r"jlong* GetLongArrayElements (JNIEnv*, jlongArray, jboolean*);", 460 | r"jfloat* GetFloatArrayElements (JNIEnv*, jfloatArray, jboolean*);", 461 | r"jdouble* GetDoubleArrayElements (JNIEnv*, jdoubleArray, jboolean*);", 462 | r"void ReleaseBooleanArrayElements (JNIEnv*, jbooleanArray, jboolean*, jint);", 463 | r"void ReleaseByteArrayElements (JNIEnv*, jbyteArray, jbyte*, jint);", 464 | r"void ReleaseCharArrayElements (JNIEnv*, jcharArray, jchar*, jint);", 465 | r"void ReleaseShortArrayElements (JNIEnv*, jshortArray, jshort*, jint);", 466 | r"void ReleaseIntArrayElements (JNIEnv*, jintArray, jint*, jint);", 467 | r"void ReleaseLongArrayElements (JNIEnv*, jlongArray, jlong*, jint);", 468 | r"void ReleaseFloatArrayElements (JNIEnv*, jfloatArray, jfloat*, jint);", 469 | r"void ReleaseDoubleArrayElements (JNIEnv*, jdoubleArray, jdouble*, jint);", 470 | r"void GetBooleanArrayRegion (JNIEnv*, jbooleanArray, jsize, jsize, jboolean*);", 471 | r"void GetByteArrayRegion (JNIEnv*, jbyteArray, jsize, jsize, jbyte*);", 472 | r"void GetCharArrayRegion (JNIEnv*, jcharArray, jsize, jsize, jchar*);", 473 | r"void GetShortArrayRegion (JNIEnv*, jshortArray, jsize, jsize, jshort*);", 474 | r"void GetIntArrayRegion (JNIEnv*, jintArray, jsize, jsize, jint*);", 475 | r"void GetLongArrayRegion (JNIEnv*, jlongArray, jsize, jsize, jlong*);", 476 | r"void GetFloatArrayRegion (JNIEnv*, jfloatArray, jsize, jsize, jfloat*);", 477 | r"void GetDoubleArrayRegion (JNIEnv*, jdoubleArray, jsize, jsize, jdouble*);", 478 | r"void SetBooleanArrayRegion (JNIEnv*, jbooleanArray, jsize, jsize, const jboolean*);", 479 | r"void SetByteArrayRegion (JNIEnv*, jbyteArray, jsize, jsize, const jbyte*);", 480 | r"void SetCharArrayRegion (JNIEnv*, jcharArray, jsize, jsize, const jchar*);", 481 | r"void SetShortArrayRegion (JNIEnv*, jshortArray, jsize, jsize, const jshort*);", 482 | r"void SetIntArrayRegion (JNIEnv*, jintArray, jsize, jsize, const jint*);", 483 | r"void SetLongArrayRegion (JNIEnv*, jlongArray, jsize, jsize, const jlong*);", 484 | r"void SetFloatArrayRegion (JNIEnv*, jfloatArray, jsize, jsize, const jfloat*);", 485 | r"void SetDoubleArrayRegion (JNIEnv*, jdoubleArray, jsize, jsize, const jdouble*);", 486 | r"jint RegisterNatives (JNIEnv*, jclass, const JNINativeMethod*, jint);", 487 | r"jint UnregisterNatives (JNIEnv*, jclass);", 488 | r"jint MonitorEnter (JNIEnv*, jobject);", 489 | r"jint MonitorExit (JNIEnv*, jobject);", 490 | r"jint GetJavaVM (JNIEnv*, JavaVM**);", 491 | r"void GetStringRegion (JNIEnv*, jstring, jsize, jsize, jchar*);", 492 | r"void GetStringUTFRegion (JNIEnv*, jstring, jsize, jsize, char*);", 493 | r"void* GetPrimitiveArrayCritical (JNIEnv*, jarray, jboolean*);", 494 | r"void ReleasePrimitiveArrayCritical (JNIEnv*, jarray, void*, jint);", 495 | r"const jchar* GetStringCritical (JNIEnv*, jstring, jboolean*);", 496 | r"void ReleaseStringCritical (JNIEnv*, jstring, const jchar*);", 497 | r"jweak NewWeakGlobalRef (JNIEnv*, jobject);", 498 | r"void DeleteWeakGlobalRef (JNIEnv*, jweak);", 499 | r"jboolean ExceptionCheck (JNIEnv*);", 500 | r"jobject NewDirectByteBuffer (JNIEnv*, void*, jlong);", 501 | r"void* GetDirectBufferAddress (JNIEnv*, jobject);", 502 | r"jlong GetDirectBufferCapacity (JNIEnv*, jobject);", 503 | r"jobjectRefType GetObjectRefType (JNIEnv*, jobject);"] 504 | 505 | JNIInvokeInterface = [ 506 | r'void* reserved0', 507 | r'void* reserved1', 508 | r'void* reserved2', 509 | r'jint (*DestroyJavaVM)(JavaVM*)', 510 | r'jint (*AttachCurrentThread)(JavaVM*, JNIEnv**, void*)', 511 | r'jint (*DetachCurrentThread)(JavaVM*)', 512 | r'jint (*GetEnv)(JavaVM*, void**, jint)', 513 | r'jint (*AttachCurrentThreadAsDaemon)(JavaVM*, JNIEnv**, void*)'] 514 | 515 | jni_jvmInterface = ["jni_DestroyJavaVM", 516 | "jni_AttachCurrentThread", 517 | "jni_DetachCurrentThread", 518 | "jni_GetEnv", 519 | "jni_AttachCurrentThreadAsDaemon"] 520 | 521 | 522 | #筛选出用户自己的函数 523 | def isUserFunc(addr): 524 | functionName = idc.get_name(idc.get_func_attr(addr,FUNCATTR_START), ida_name.GN_VISIBLE) 525 | if functionName.startswith('_'): 526 | return False 527 | return True 528 | 529 | #判断寄存器是否被指定的操作码 和 操作码类型修改 530 | def FirstWriteRegOp( addr,reg,op,Optype = None): 531 | addr = ida_search.find_code(addr,SEARCH_NEXT) 532 | while (addr != BADADDR): 533 | #第一个操作数是指定寄存器 534 | if idc.print_operand(addr,0) == reg: 535 | #操作码相同 536 | if idc.print_insn_mnem(addr) == op: 537 | if Optype == None: 538 | return addr 539 | elif Optype == idc.get_operand_type(addr,1): 540 | return addr 541 | return 0 542 | else: 543 | return 0 544 | addr = ida_search.find_code(addr,SEARCH_NEXT) 545 | return 0 546 | 547 | #往上回朔,找到第一次操作指定寄存器的地址 548 | def writeRegAddr(addr ,reg): 549 | addr = ida_search.find_code(addr,SEARCH_NEXT) 550 | while (addr != BADADDR): 551 | if idc.print_operand(addr,0) == reg: 552 | return addr 553 | addr = ida_search.find_code(addr,SEARCH_NEXT) 554 | return 0 555 | 556 | def setComment(addr,offset): 557 | if (offset / 4) < len(JNINativeInterface) and (offset / 4) >= 4: 558 | comment = JNINativeInterface[offset / 4] 559 | idc.set_cmt(addr, comment, 1) 560 | print('set comment 0x%x' % addr) 561 | 562 | def setEnumAndCom(addr): 563 | offset = idc.get_operand_value(addr,1) 564 | if (offset / 4) < len(JNINativeInterface) and (offset / 4) >= 4: 565 | comment = JNINativeInterface[int(offset / 4)] 566 | #添加注释 567 | idc.set_cmt(addr, comment, 1) 568 | #设为枚举类型 569 | idc.op_enum(addr,1,enum_jni_id,0) 570 | print('set comment and enum 0x%x' % addr) 571 | 572 | def find_LDR(addr, reg): 573 | addr = ida_search.find_code(addr,SEARCH_NEXT) 574 | while (addr != BADADDR): 575 | 576 | #查找指定LDR LDR REG,[XXXX,XXXX] 577 | if idc.print_insn_mnem(addr) == 'LDR' and idc.print_operand(addr,0) == reg: 578 | #print idc.print_operand(addr,1),GetOpType(addr,1) 579 | 580 | #右侧的寄存器列表 581 | regs = filter(lambda x: x.startswith('R') , idc.print_operand(addr,1)[1:-1].split(',')) 582 | regs = list(regs) 583 | if len(regs) == 0: 584 | addr = ida_search.find_code(addr,SEARCH_NEXT) 585 | continue 586 | 587 | # LDR RX,[RX,#0xXX] 588 | if idc.get_operand_type(addr,1) == OP_Base_Index_Displacement: 589 | #可能是通过 Table + offset 调用的 590 | if FirstWriteRegOp( addr, regs[0],'LDR',OP_Base_Index_Displacement): 591 | #第一个寄存器可能是基地址 592 | setEnumAndCom(addr) 593 | return 594 | else: 595 | # [RX,#0xXX] RX 不确定第一个寄存器来源 596 | off = idc.get_operand_value(addr, 1) 597 | 598 | if len(regs) == 1: 599 | #LDR RX,[RY + 0xXX] 600 | #单个寄存器 601 | wRegaddr = writeRegAddr(addr,regs[0]) 602 | if idc.print_insn_mnem(wRegaddr) == 'ADD' and FirstWriteRegOp(wRegaddr, regs[0],'LDR',OP_Base_Index): 603 | off2 = idc.get_operand_value(wRegaddr, 1) 604 | offset = off + off2 605 | if off != 0: 606 | setComment( addr , offset) 607 | else: 608 | setEnumAndCom(wRegaddr) 609 | return 610 | print('0x%x Do not support! 0x04' % addr) 611 | return 612 | 613 | elif len(regs) > 1 : 614 | #LDR RX,[RY+ RZ +0xXX] 615 | #多个寄存器 616 | print('0x%x Do not support! 0x05' % addr) 617 | return 618 | 619 | 620 | #基地址寄存器可能已经包含偏移 621 | print('0x%x Do not support! 0x03' % addr) 622 | return 623 | 624 | 625 | #EXP: LDR R3,[R1,R2] 626 | elif idc.get_operand_type(addr,1) == OP_Base_Index: 627 | 628 | # 第一个寄存器可能是基地址 629 | if FirstWriteRegOp( addr, regs[0],'LDR', OP_Base_Index_Displacement) > 0: 630 | #第二个寄存器是mov指令直接设定的偏移值 631 | wRegAddr = FirstWriteRegOp( addr ,regs[1],"MOV", OP_Immediate) 632 | if wRegAddr > 0: 633 | setEnumAndCom(wRegAddr) 634 | return 635 | 636 | wRegAddr = FirstWriteRegOp( addr ,regs[1],"LSL", OP_Immediate) 637 | if wRegAddr > 0: 638 | print('LSL 0x%x' % wRegAddr) 639 | #setEnumAndCom(wRegAddr) 640 | return 641 | else: 642 | print('0x%x Do not support! 0x02' % addr) 643 | print(idc.print_operand(addr,1),idc.get_operand_type(addr,1)) 644 | 645 | 646 | elif idc.print_operand(addr,0) == reg: 647 | print('0x%x Do not support! 0x01' % addr) 648 | return 649 | addr = ida_search.find_code(addr,SEARCH_NEXT) 650 | 651 | 652 | #修改指定地址范围中的JNI调用 653 | def modify_jni_call(start,end): 654 | addr = end 655 | while (addr > start): 656 | #逆向遍历指令 657 | addr = ida_search.find_code(addr,SEARCH_NEXT) 658 | #BLX操作 659 | if idc.print_insn_mnem(addr) == "BLX": 660 | #左边第一个操作数 661 | Opnd0 = idc.print_operand(addr,0) 662 | if Opnd0 in COMMON_REG: 663 | #print '%x %s %s'% (addr,idc.print_insn_mnem(addr),idc.print_operand(addr,0)) 664 | find_LDR(addr, Opnd0) 665 | pass 666 | 667 | pass 668 | 669 | #列出所有函数 670 | def enum_user_function(): 671 | modified = 0 672 | addr = idc.get_next_func( 0 ) 673 | while (addr != BADADDR): 674 | function_start = addr 675 | function_end = idc.get_func_attr(addr,FUNCATTR_END) 676 | #过滤出用户的函数 677 | if isUserFunc(addr): 678 | #尝试校正 679 | modify_jni_call(function_start,function_end) 680 | 681 | addr = idc.get_next_func(addr) 682 | 683 | def init_enum(enum_name, fields_list , offset ,comments): 684 | ret_id = idc.add_enum(-1,enum_name,0x1100000); 685 | synthesis = list() 686 | 687 | #将枚举成员,原型声明合并 688 | for i in range(len(fields_list)): 689 | synthesis.append((fields_list[i],comments[i],)) 690 | 691 | if ret_id != 0xFFFFFFFF: 692 | for fun,com in synthesis: 693 | idc.add_enum_member( ret_id , fun , offset , -1); 694 | ida_enum.set_enum_member_cmt(idc.get_enum_member(ret_id,offset,0,-1),com ,1); 695 | offset += 4 696 | return ret_id 697 | 698 | #2014/09/10 10:20 699 | #获取枚举 700 | enum_jni_id = ida_enum.get_enum(Enum_JNI_Name) 701 | 702 | init_enum( 'JNI_JVM_FUNC', jni_jvmInterface, 12,JNIInvokeInterface[3:]) 703 | 704 | if enum_jni_id == 0xFFFFFFFF: 705 | #不存在,则创建 706 | print('create enum') 707 | enum_jni_id = init_enum(Enum_JNI_Name, jni_names_list,0x10,JNINativeInterface[4:]) 708 | 709 | elif ida_enum.get_enum_size(enum_jni_id) != len(jni_names_list): 710 | #成员个数不对,重新创建 711 | print('delete enum %s' % Enum_JNI_Name) 712 | ida_enum.del_enum(enum_jni_id) 713 | enum_jni_id = init_enum(Enum_JNI_Name, jni_names_list,0x10,JNINativeInterface[4:]) 714 | 715 | else: 716 | print('enum has been created!') 717 | 718 | if (enum_jni_id != 0xFFFFFFFF): 719 | #遍历用户函数 720 | enum_user_function() 721 | print('Set jni name Finish!!!') 722 | else: 723 | print('Create enum fail!!!') 724 | 725 | -------------------------------------------------------------------------------- /IDA/IDA_JNI_Rename/jni-api19.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2006 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* 18 | * JNI specification, as defined by Sun: 19 | * http://java.sun.com/javase/6/docs/technotes/guides/jni/spec/jniTOC.html 20 | * 21 | * Everything here is expected to be VM-neutral. 22 | */ 23 | 24 | #ifndef JNI_H_ 25 | #define JNI_H_ 26 | 27 | #include 28 | #include 29 | 30 | /* 31 | * Primitive types that match up with Java equivalents. 32 | */ 33 | #ifdef HAVE_INTTYPES_H 34 | # include /* C99 */ 35 | typedef uint8_t jboolean; /* unsigned 8 bits */ 36 | typedef int8_t jbyte; /* signed 8 bits */ 37 | typedef uint16_t jchar; /* unsigned 16 bits */ 38 | typedef int16_t jshort; /* signed 16 bits */ 39 | typedef int32_t jint; /* signed 32 bits */ 40 | typedef int64_t jlong; /* signed 64 bits */ 41 | typedef float jfloat; /* 32-bit IEEE 754 */ 42 | typedef double jdouble; /* 64-bit IEEE 754 */ 43 | #else 44 | typedef unsigned char jboolean; /* unsigned 8 bits */ 45 | typedef signed char jbyte; /* signed 8 bits */ 46 | typedef unsigned short jchar; /* unsigned 16 bits */ 47 | typedef short jshort; /* signed 16 bits */ 48 | typedef int jint; /* signed 32 bits */ 49 | typedef long long jlong; /* signed 64 bits */ 50 | typedef float jfloat; /* 32-bit IEEE 754 */ 51 | typedef double jdouble; /* 64-bit IEEE 754 */ 52 | #endif 53 | 54 | /* "cardinal indices and sizes" */ 55 | typedef jint jsize; 56 | 57 | #ifdef __cplusplus 58 | /* 59 | * Reference types, in C++ 60 | */ 61 | class _jobject {}; 62 | class _jclass : public _jobject {}; 63 | class _jstring : public _jobject {}; 64 | class _jarray : public _jobject {}; 65 | class _jobjectArray : public _jarray {}; 66 | class _jbooleanArray : public _jarray {}; 67 | class _jbyteArray : public _jarray {}; 68 | class _jcharArray : public _jarray {}; 69 | class _jshortArray : public _jarray {}; 70 | class _jintArray : public _jarray {}; 71 | class _jlongArray : public _jarray {}; 72 | class _jfloatArray : public _jarray {}; 73 | class _jdoubleArray : public _jarray {}; 74 | class _jthrowable : public _jobject {}; 75 | 76 | typedef _jobject* jobject; 77 | typedef _jclass* jclass; 78 | typedef _jstring* jstring; 79 | typedef _jarray* jarray; 80 | typedef _jobjectArray* jobjectArray; 81 | typedef _jbooleanArray* jbooleanArray; 82 | typedef _jbyteArray* jbyteArray; 83 | typedef _jcharArray* jcharArray; 84 | typedef _jshortArray* jshortArray; 85 | typedef _jintArray* jintArray; 86 | typedef _jlongArray* jlongArray; 87 | typedef _jfloatArray* jfloatArray; 88 | typedef _jdoubleArray* jdoubleArray; 89 | typedef _jthrowable* jthrowable; 90 | typedef _jobject* jweak; 91 | 92 | 93 | #else /* not __cplusplus */ 94 | 95 | /* 96 | * Reference types, in C. 97 | */ 98 | typedef void* jobject; 99 | typedef jobject jclass; 100 | typedef jobject jstring; 101 | typedef jobject jarray; 102 | typedef jarray jobjectArray; 103 | typedef jarray jbooleanArray; 104 | typedef jarray jbyteArray; 105 | typedef jarray jcharArray; 106 | typedef jarray jshortArray; 107 | typedef jarray jintArray; 108 | typedef jarray jlongArray; 109 | typedef jarray jfloatArray; 110 | typedef jarray jdoubleArray; 111 | typedef jobject jthrowable; 112 | typedef jobject jweak; 113 | 114 | #endif /* not __cplusplus */ 115 | 116 | struct _jfieldID; /* opaque structure */ 117 | typedef struct _jfieldID* jfieldID; /* field IDs */ 118 | 119 | struct _jmethodID; /* opaque structure */ 120 | typedef struct _jmethodID* jmethodID; /* method IDs */ 121 | 122 | struct JNIInvokeInterface; 123 | 124 | typedef union jvalue { 125 | jboolean z; 126 | jbyte b; 127 | jchar c; 128 | jshort s; 129 | jint i; 130 | jlong j; 131 | jfloat f; 132 | jdouble d; 133 | jobject l; 134 | } jvalue; 135 | 136 | typedef enum jobjectRefType { 137 | JNIInvalidRefType = 0, 138 | JNILocalRefType = 1, 139 | JNIGlobalRefType = 2, 140 | JNIWeakGlobalRefType = 3 141 | } jobjectRefType; 142 | 143 | typedef struct { 144 | const char* name; 145 | const char* signature; 146 | void* fnPtr; 147 | } JNINativeMethod; 148 | 149 | struct _JNIEnv; 150 | struct _JavaVM; 151 | typedef const struct JNINativeInterface* C_JNIEnv; 152 | 153 | #if defined(__cplusplus) 154 | typedef _JNIEnv JNIEnv; 155 | typedef _JavaVM JavaVM; 156 | #else 157 | typedef const struct JNINativeInterface* JNIEnv; 158 | typedef const struct JNIInvokeInterface* JavaVM; 159 | #endif 160 | 161 | /* 162 | * Table of interface function pointers. 163 | */ 164 | struct JNINativeInterface { 165 | void* reserved0; 166 | void* reserved1; 167 | void* reserved2; 168 | void* reserved3; 169 | 170 | jint (*GetVersion)(JNIEnv *); 171 | 172 | jclass (*DefineClass)(JNIEnv*, const char*, jobject, const jbyte*, 173 | jsize); 174 | jclass (*FindClass)(JNIEnv*, const char*); 175 | 176 | jmethodID (*FromReflectedMethod)(JNIEnv*, jobject); 177 | jfieldID (*FromReflectedField)(JNIEnv*, jobject); 178 | /* spec doesn't show jboolean parameter */ 179 | jobject (*ToReflectedMethod)(JNIEnv*, jclass, jmethodID, jboolean); 180 | 181 | jclass (*GetSuperclass)(JNIEnv*, jclass); 182 | jboolean (*IsAssignableFrom)(JNIEnv*, jclass, jclass); 183 | 184 | /* spec doesn't show jboolean parameter */ 185 | jobject (*ToReflectedField)(JNIEnv*, jclass, jfieldID, jboolean); 186 | 187 | jint (*Throw)(JNIEnv*, jthrowable); 188 | jint (*ThrowNew)(JNIEnv *, jclass, const char *); 189 | jthrowable (*ExceptionOccurred)(JNIEnv*); 190 | void (*ExceptionDescribe)(JNIEnv*); 191 | void (*ExceptionClear)(JNIEnv*); 192 | void (*FatalError)(JNIEnv*, const char*); 193 | 194 | jint (*PushLocalFrame)(JNIEnv*, jint); 195 | jobject (*PopLocalFrame)(JNIEnv*, jobject); 196 | 197 | jobject (*NewGlobalRef)(JNIEnv*, jobject); 198 | void (*DeleteGlobalRef)(JNIEnv*, jobject); 199 | void (*DeleteLocalRef)(JNIEnv*, jobject); 200 | jboolean (*IsSameObject)(JNIEnv*, jobject, jobject); 201 | 202 | jobject (*NewLocalRef)(JNIEnv*, jobject); 203 | jint (*EnsureLocalCapacity)(JNIEnv*, jint); 204 | 205 | jobject (*AllocObject)(JNIEnv*, jclass); 206 | jobject (*NewObject)(JNIEnv*, jclass, jmethodID, ...); 207 | jobject (*NewObjectV)(JNIEnv*, jclass, jmethodID, va_list); 208 | jobject (*NewObjectA)(JNIEnv*, jclass, jmethodID, jvalue*); 209 | 210 | jclass (*GetObjectClass)(JNIEnv*, jobject); 211 | jboolean (*IsInstanceOf)(JNIEnv*, jobject, jclass); 212 | jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*); 213 | 214 | jobject (*CallObjectMethod)(JNIEnv*, jobject, jmethodID, ...); 215 | jobject (*CallObjectMethodV)(JNIEnv*, jobject, jmethodID, va_list); 216 | jobject (*CallObjectMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); 217 | jboolean (*CallBooleanMethod)(JNIEnv*, jobject, jmethodID, ...); 218 | jboolean (*CallBooleanMethodV)(JNIEnv*, jobject, jmethodID, va_list); 219 | jboolean (*CallBooleanMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); 220 | jbyte (*CallByteMethod)(JNIEnv*, jobject, jmethodID, ...); 221 | jbyte (*CallByteMethodV)(JNIEnv*, jobject, jmethodID, va_list); 222 | jbyte (*CallByteMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); 223 | jchar (*CallCharMethod)(JNIEnv*, jobject, jmethodID, ...); 224 | jchar (*CallCharMethodV)(JNIEnv*, jobject, jmethodID, va_list); 225 | jchar (*CallCharMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); 226 | jshort (*CallShortMethod)(JNIEnv*, jobject, jmethodID, ...); 227 | jshort (*CallShortMethodV)(JNIEnv*, jobject, jmethodID, va_list); 228 | jshort (*CallShortMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); 229 | jint (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...); 230 | jint (*CallIntMethodV)(JNIEnv*, jobject, jmethodID, va_list); 231 | jint (*CallIntMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); 232 | jlong (*CallLongMethod)(JNIEnv*, jobject, jmethodID, ...); 233 | jlong (*CallLongMethodV)(JNIEnv*, jobject, jmethodID, va_list); 234 | jlong (*CallLongMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); 235 | jfloat (*CallFloatMethod)(JNIEnv*, jobject, jmethodID, ...) __NDK_FPABI__; 236 | jfloat (*CallFloatMethodV)(JNIEnv*, jobject, jmethodID, va_list) __NDK_FPABI__; 237 | jfloat (*CallFloatMethodA)(JNIEnv*, jobject, jmethodID, jvalue*) __NDK_FPABI__; 238 | jdouble (*CallDoubleMethod)(JNIEnv*, jobject, jmethodID, ...) __NDK_FPABI__; 239 | jdouble (*CallDoubleMethodV)(JNIEnv*, jobject, jmethodID, va_list) __NDK_FPABI__; 240 | jdouble (*CallDoubleMethodA)(JNIEnv*, jobject, jmethodID, jvalue*) __NDK_FPABI__; 241 | void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...); 242 | void (*CallVoidMethodV)(JNIEnv*, jobject, jmethodID, va_list); 243 | void (*CallVoidMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); 244 | 245 | jobject (*CallNonvirtualObjectMethod)(JNIEnv*, jobject, jclass, 246 | jmethodID, ...); 247 | jobject (*CallNonvirtualObjectMethodV)(JNIEnv*, jobject, jclass, 248 | jmethodID, va_list); 249 | jobject (*CallNonvirtualObjectMethodA)(JNIEnv*, jobject, jclass, 250 | jmethodID, jvalue*); 251 | jboolean (*CallNonvirtualBooleanMethod)(JNIEnv*, jobject, jclass, 252 | jmethodID, ...); 253 | jboolean (*CallNonvirtualBooleanMethodV)(JNIEnv*, jobject, jclass, 254 | jmethodID, va_list); 255 | jboolean (*CallNonvirtualBooleanMethodA)(JNIEnv*, jobject, jclass, 256 | jmethodID, jvalue*); 257 | jbyte (*CallNonvirtualByteMethod)(JNIEnv*, jobject, jclass, 258 | jmethodID, ...); 259 | jbyte (*CallNonvirtualByteMethodV)(JNIEnv*, jobject, jclass, 260 | jmethodID, va_list); 261 | jbyte (*CallNonvirtualByteMethodA)(JNIEnv*, jobject, jclass, 262 | jmethodID, jvalue*); 263 | jchar (*CallNonvirtualCharMethod)(JNIEnv*, jobject, jclass, 264 | jmethodID, ...); 265 | jchar (*CallNonvirtualCharMethodV)(JNIEnv*, jobject, jclass, 266 | jmethodID, va_list); 267 | jchar (*CallNonvirtualCharMethodA)(JNIEnv*, jobject, jclass, 268 | jmethodID, jvalue*); 269 | jshort (*CallNonvirtualShortMethod)(JNIEnv*, jobject, jclass, 270 | jmethodID, ...); 271 | jshort (*CallNonvirtualShortMethodV)(JNIEnv*, jobject, jclass, 272 | jmethodID, va_list); 273 | jshort (*CallNonvirtualShortMethodA)(JNIEnv*, jobject, jclass, 274 | jmethodID, jvalue*); 275 | jint (*CallNonvirtualIntMethod)(JNIEnv*, jobject, jclass, 276 | jmethodID, ...); 277 | jint (*CallNonvirtualIntMethodV)(JNIEnv*, jobject, jclass, 278 | jmethodID, va_list); 279 | jint (*CallNonvirtualIntMethodA)(JNIEnv*, jobject, jclass, 280 | jmethodID, jvalue*); 281 | jlong (*CallNonvirtualLongMethod)(JNIEnv*, jobject, jclass, 282 | jmethodID, ...); 283 | jlong (*CallNonvirtualLongMethodV)(JNIEnv*, jobject, jclass, 284 | jmethodID, va_list); 285 | jlong (*CallNonvirtualLongMethodA)(JNIEnv*, jobject, jclass, 286 | jmethodID, jvalue*); 287 | jfloat (*CallNonvirtualFloatMethod)(JNIEnv*, jobject, jclass, 288 | jmethodID, ...) __NDK_FPABI__; 289 | jfloat (*CallNonvirtualFloatMethodV)(JNIEnv*, jobject, jclass, 290 | jmethodID, va_list) __NDK_FPABI__; 291 | jfloat (*CallNonvirtualFloatMethodA)(JNIEnv*, jobject, jclass, 292 | jmethodID, jvalue*) __NDK_FPABI__; 293 | jdouble (*CallNonvirtualDoubleMethod)(JNIEnv*, jobject, jclass, 294 | jmethodID, ...) __NDK_FPABI__; 295 | jdouble (*CallNonvirtualDoubleMethodV)(JNIEnv*, jobject, jclass, 296 | jmethodID, va_list) __NDK_FPABI__; 297 | jdouble (*CallNonvirtualDoubleMethodA)(JNIEnv*, jobject, jclass, 298 | jmethodID, jvalue*) __NDK_FPABI__; 299 | void (*CallNonvirtualVoidMethod)(JNIEnv*, jobject, jclass, 300 | jmethodID, ...); 301 | void (*CallNonvirtualVoidMethodV)(JNIEnv*, jobject, jclass, 302 | jmethodID, va_list); 303 | void (*CallNonvirtualVoidMethodA)(JNIEnv*, jobject, jclass, 304 | jmethodID, jvalue*); 305 | 306 | jfieldID (*GetFieldID)(JNIEnv*, jclass, const char*, const char*); 307 | 308 | jobject (*GetObjectField)(JNIEnv*, jobject, jfieldID); 309 | jboolean (*GetBooleanField)(JNIEnv*, jobject, jfieldID); 310 | jbyte (*GetByteField)(JNIEnv*, jobject, jfieldID); 311 | jchar (*GetCharField)(JNIEnv*, jobject, jfieldID); 312 | jshort (*GetShortField)(JNIEnv*, jobject, jfieldID); 313 | jint (*GetIntField)(JNIEnv*, jobject, jfieldID); 314 | jlong (*GetLongField)(JNIEnv*, jobject, jfieldID); 315 | jfloat (*GetFloatField)(JNIEnv*, jobject, jfieldID) __NDK_FPABI__; 316 | jdouble (*GetDoubleField)(JNIEnv*, jobject, jfieldID) __NDK_FPABI__; 317 | 318 | void (*SetObjectField)(JNIEnv*, jobject, jfieldID, jobject); 319 | void (*SetBooleanField)(JNIEnv*, jobject, jfieldID, jboolean); 320 | void (*SetByteField)(JNIEnv*, jobject, jfieldID, jbyte); 321 | void (*SetCharField)(JNIEnv*, jobject, jfieldID, jchar); 322 | void (*SetShortField)(JNIEnv*, jobject, jfieldID, jshort); 323 | void (*SetIntField)(JNIEnv*, jobject, jfieldID, jint); 324 | void (*SetLongField)(JNIEnv*, jobject, jfieldID, jlong); 325 | void (*SetFloatField)(JNIEnv*, jobject, jfieldID, jfloat) __NDK_FPABI__; 326 | void (*SetDoubleField)(JNIEnv*, jobject, jfieldID, jdouble) __NDK_FPABI__; 327 | 328 | jmethodID (*GetStaticMethodID)(JNIEnv*, jclass, const char*, const char*); 329 | 330 | jobject (*CallStaticObjectMethod)(JNIEnv*, jclass, jmethodID, ...); 331 | jobject (*CallStaticObjectMethodV)(JNIEnv*, jclass, jmethodID, va_list); 332 | jobject (*CallStaticObjectMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); 333 | jboolean (*CallStaticBooleanMethod)(JNIEnv*, jclass, jmethodID, ...); 334 | jboolean (*CallStaticBooleanMethodV)(JNIEnv*, jclass, jmethodID, 335 | va_list); 336 | jboolean (*CallStaticBooleanMethodA)(JNIEnv*, jclass, jmethodID, 337 | jvalue*); 338 | jbyte (*CallStaticByteMethod)(JNIEnv*, jclass, jmethodID, ...); 339 | jbyte (*CallStaticByteMethodV)(JNIEnv*, jclass, jmethodID, va_list); 340 | jbyte (*CallStaticByteMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); 341 | jchar (*CallStaticCharMethod)(JNIEnv*, jclass, jmethodID, ...); 342 | jchar (*CallStaticCharMethodV)(JNIEnv*, jclass, jmethodID, va_list); 343 | jchar (*CallStaticCharMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); 344 | jshort (*CallStaticShortMethod)(JNIEnv*, jclass, jmethodID, ...); 345 | jshort (*CallStaticShortMethodV)(JNIEnv*, jclass, jmethodID, va_list); 346 | jshort (*CallStaticShortMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); 347 | jint (*CallStaticIntMethod)(JNIEnv*, jclass, jmethodID, ...); 348 | jint (*CallStaticIntMethodV)(JNIEnv*, jclass, jmethodID, va_list); 349 | jint (*CallStaticIntMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); 350 | jlong (*CallStaticLongMethod)(JNIEnv*, jclass, jmethodID, ...); 351 | jlong (*CallStaticLongMethodV)(JNIEnv*, jclass, jmethodID, va_list); 352 | jlong (*CallStaticLongMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); 353 | jfloat (*CallStaticFloatMethod)(JNIEnv*, jclass, jmethodID, ...) __NDK_FPABI__; 354 | jfloat (*CallStaticFloatMethodV)(JNIEnv*, jclass, jmethodID, va_list) __NDK_FPABI__; 355 | jfloat (*CallStaticFloatMethodA)(JNIEnv*, jclass, jmethodID, jvalue*) __NDK_FPABI__; 356 | jdouble (*CallStaticDoubleMethod)(JNIEnv*, jclass, jmethodID, ...) __NDK_FPABI__; 357 | jdouble (*CallStaticDoubleMethodV)(JNIEnv*, jclass, jmethodID, va_list) __NDK_FPABI__; 358 | jdouble (*CallStaticDoubleMethodA)(JNIEnv*, jclass, jmethodID, jvalue*) __NDK_FPABI__; 359 | void (*CallStaticVoidMethod)(JNIEnv*, jclass, jmethodID, ...); 360 | void (*CallStaticVoidMethodV)(JNIEnv*, jclass, jmethodID, va_list); 361 | void (*CallStaticVoidMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); 362 | 363 | jfieldID (*GetStaticFieldID)(JNIEnv*, jclass, const char*, 364 | const char*); 365 | 366 | jobject (*GetStaticObjectField)(JNIEnv*, jclass, jfieldID); 367 | jboolean (*GetStaticBooleanField)(JNIEnv*, jclass, jfieldID); 368 | jbyte (*GetStaticByteField)(JNIEnv*, jclass, jfieldID); 369 | jchar (*GetStaticCharField)(JNIEnv*, jclass, jfieldID); 370 | jshort (*GetStaticShortField)(JNIEnv*, jclass, jfieldID); 371 | jint (*GetStaticIntField)(JNIEnv*, jclass, jfieldID); 372 | jlong (*GetStaticLongField)(JNIEnv*, jclass, jfieldID); 373 | jfloat (*GetStaticFloatField)(JNIEnv*, jclass, jfieldID) __NDK_FPABI__; 374 | jdouble (*GetStaticDoubleField)(JNIEnv*, jclass, jfieldID) __NDK_FPABI__; 375 | 376 | void (*SetStaticObjectField)(JNIEnv*, jclass, jfieldID, jobject); 377 | void (*SetStaticBooleanField)(JNIEnv*, jclass, jfieldID, jboolean); 378 | void (*SetStaticByteField)(JNIEnv*, jclass, jfieldID, jbyte); 379 | void (*SetStaticCharField)(JNIEnv*, jclass, jfieldID, jchar); 380 | void (*SetStaticShortField)(JNIEnv*, jclass, jfieldID, jshort); 381 | void (*SetStaticIntField)(JNIEnv*, jclass, jfieldID, jint); 382 | void (*SetStaticLongField)(JNIEnv*, jclass, jfieldID, jlong); 383 | void (*SetStaticFloatField)(JNIEnv*, jclass, jfieldID, jfloat) __NDK_FPABI__; 384 | void (*SetStaticDoubleField)(JNIEnv*, jclass, jfieldID, jdouble) __NDK_FPABI__; 385 | 386 | jstring (*NewString)(JNIEnv*, const jchar*, jsize); 387 | jsize (*GetStringLength)(JNIEnv*, jstring); 388 | const jchar* (*GetStringChars)(JNIEnv*, jstring, jboolean*); 389 | void (*ReleaseStringChars)(JNIEnv*, jstring, const jchar*); 390 | jstring (*NewStringUTF)(JNIEnv*, const char*); 391 | jsize (*GetStringUTFLength)(JNIEnv*, jstring); 392 | /* JNI spec says this returns const jbyte*, but that's inconsistent */ 393 | const char* (*GetStringUTFChars)(JNIEnv*, jstring, jboolean*); 394 | void (*ReleaseStringUTFChars)(JNIEnv*, jstring, const char*); 395 | jsize (*GetArrayLength)(JNIEnv*, jarray); 396 | jobjectArray (*NewObjectArray)(JNIEnv*, jsize, jclass, jobject); 397 | jobject (*GetObjectArrayElement)(JNIEnv*, jobjectArray, jsize); 398 | void (*SetObjectArrayElement)(JNIEnv*, jobjectArray, jsize, jobject); 399 | 400 | jbooleanArray (*NewBooleanArray)(JNIEnv*, jsize); 401 | jbyteArray (*NewByteArray)(JNIEnv*, jsize); 402 | jcharArray (*NewCharArray)(JNIEnv*, jsize); 403 | jshortArray (*NewShortArray)(JNIEnv*, jsize); 404 | jintArray (*NewIntArray)(JNIEnv*, jsize); 405 | jlongArray (*NewLongArray)(JNIEnv*, jsize); 406 | jfloatArray (*NewFloatArray)(JNIEnv*, jsize); 407 | jdoubleArray (*NewDoubleArray)(JNIEnv*, jsize); 408 | 409 | jboolean* (*GetBooleanArrayElements)(JNIEnv*, jbooleanArray, jboolean*); 410 | jbyte* (*GetByteArrayElements)(JNIEnv*, jbyteArray, jboolean*); 411 | jchar* (*GetCharArrayElements)(JNIEnv*, jcharArray, jboolean*); 412 | jshort* (*GetShortArrayElements)(JNIEnv*, jshortArray, jboolean*); 413 | jint* (*GetIntArrayElements)(JNIEnv*, jintArray, jboolean*); 414 | jlong* (*GetLongArrayElements)(JNIEnv*, jlongArray, jboolean*); 415 | jfloat* (*GetFloatArrayElements)(JNIEnv*, jfloatArray, jboolean*); 416 | jdouble* (*GetDoubleArrayElements)(JNIEnv*, jdoubleArray, jboolean*); 417 | 418 | void (*ReleaseBooleanArrayElements)(JNIEnv*, jbooleanArray, 419 | jboolean*, jint); 420 | void (*ReleaseByteArrayElements)(JNIEnv*, jbyteArray, 421 | jbyte*, jint); 422 | void (*ReleaseCharArrayElements)(JNIEnv*, jcharArray, 423 | jchar*, jint); 424 | void (*ReleaseShortArrayElements)(JNIEnv*, jshortArray, 425 | jshort*, jint); 426 | void (*ReleaseIntArrayElements)(JNIEnv*, jintArray, 427 | jint*, jint); 428 | void (*ReleaseLongArrayElements)(JNIEnv*, jlongArray, 429 | jlong*, jint); 430 | void (*ReleaseFloatArrayElements)(JNIEnv*, jfloatArray, 431 | jfloat*, jint); 432 | void (*ReleaseDoubleArrayElements)(JNIEnv*, jdoubleArray, 433 | jdouble*, jint); 434 | 435 | void (*GetBooleanArrayRegion)(JNIEnv*, jbooleanArray, 436 | jsize, jsize, jboolean*); 437 | void (*GetByteArrayRegion)(JNIEnv*, jbyteArray, 438 | jsize, jsize, jbyte*); 439 | void (*GetCharArrayRegion)(JNIEnv*, jcharArray, 440 | jsize, jsize, jchar*); 441 | void (*GetShortArrayRegion)(JNIEnv*, jshortArray, 442 | jsize, jsize, jshort*); 443 | void (*GetIntArrayRegion)(JNIEnv*, jintArray, 444 | jsize, jsize, jint*); 445 | void (*GetLongArrayRegion)(JNIEnv*, jlongArray, 446 | jsize, jsize, jlong*); 447 | void (*GetFloatArrayRegion)(JNIEnv*, jfloatArray, 448 | jsize, jsize, jfloat*); 449 | void (*GetDoubleArrayRegion)(JNIEnv*, jdoubleArray, 450 | jsize, jsize, jdouble*); 451 | 452 | /* spec shows these without const; some jni.h do, some don't */ 453 | void (*SetBooleanArrayRegion)(JNIEnv*, jbooleanArray, 454 | jsize, jsize, const jboolean*); 455 | void (*SetByteArrayRegion)(JNIEnv*, jbyteArray, 456 | jsize, jsize, const jbyte*); 457 | void (*SetCharArrayRegion)(JNIEnv*, jcharArray, 458 | jsize, jsize, const jchar*); 459 | void (*SetShortArrayRegion)(JNIEnv*, jshortArray, 460 | jsize, jsize, const jshort*); 461 | void (*SetIntArrayRegion)(JNIEnv*, jintArray, 462 | jsize, jsize, const jint*); 463 | void (*SetLongArrayRegion)(JNIEnv*, jlongArray, 464 | jsize, jsize, const jlong*); 465 | void (*SetFloatArrayRegion)(JNIEnv*, jfloatArray, 466 | jsize, jsize, const jfloat*); 467 | void (*SetDoubleArrayRegion)(JNIEnv*, jdoubleArray, 468 | jsize, jsize, const jdouble*); 469 | 470 | jint (*RegisterNatives)(JNIEnv*, jclass, const JNINativeMethod*, 471 | jint); 472 | jint (*UnregisterNatives)(JNIEnv*, jclass); 473 | jint (*MonitorEnter)(JNIEnv*, jobject); 474 | jint (*MonitorExit)(JNIEnv*, jobject); 475 | jint (*GetJavaVM)(JNIEnv*, JavaVM**); 476 | 477 | void (*GetStringRegion)(JNIEnv*, jstring, jsize, jsize, jchar*); 478 | void (*GetStringUTFRegion)(JNIEnv*, jstring, jsize, jsize, char*); 479 | 480 | void* (*GetPrimitiveArrayCritical)(JNIEnv*, jarray, jboolean*); 481 | void (*ReleasePrimitiveArrayCritical)(JNIEnv*, jarray, void*, jint); 482 | 483 | const jchar* (*GetStringCritical)(JNIEnv*, jstring, jboolean*); 484 | void (*ReleaseStringCritical)(JNIEnv*, jstring, const jchar*); 485 | 486 | jweak (*NewWeakGlobalRef)(JNIEnv*, jobject); 487 | void (*DeleteWeakGlobalRef)(JNIEnv*, jweak); 488 | 489 | jboolean (*ExceptionCheck)(JNIEnv*); 490 | 491 | jobject (*NewDirectByteBuffer)(JNIEnv*, void*, jlong); 492 | void* (*GetDirectBufferAddress)(JNIEnv*, jobject); 493 | jlong (*GetDirectBufferCapacity)(JNIEnv*, jobject); 494 | 495 | /* added in JNI 1.6 */ 496 | jobjectRefType (*GetObjectRefType)(JNIEnv*, jobject); 497 | }; 498 | 499 | /* 500 | * C++ object wrapper. 501 | * 502 | * This is usually overlaid on a C struct whose first element is a 503 | * JNINativeInterface*. We rely somewhat on compiler behavior. 504 | */ 505 | struct _JNIEnv { 506 | /* do not rename this; it does not seem to be entirely opaque */ 507 | const struct JNINativeInterface* functions; 508 | 509 | #if defined(__cplusplus) 510 | 511 | jint GetVersion() 512 | { return functions->GetVersion(this); } 513 | 514 | jclass DefineClass(const char *name, jobject loader, const jbyte* buf, 515 | jsize bufLen) 516 | { return functions->DefineClass(this, name, loader, buf, bufLen); } 517 | 518 | jclass FindClass(const char* name) 519 | { return functions->FindClass(this, name); } 520 | 521 | jmethodID FromReflectedMethod(jobject method) 522 | { return functions->FromReflectedMethod(this, method); } 523 | 524 | jfieldID FromReflectedField(jobject field) 525 | { return functions->FromReflectedField(this, field); } 526 | 527 | jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic) 528 | { return functions->ToReflectedMethod(this, cls, methodID, isStatic); } 529 | 530 | jclass GetSuperclass(jclass clazz) 531 | { return functions->GetSuperclass(this, clazz); } 532 | 533 | jboolean IsAssignableFrom(jclass clazz1, jclass clazz2) 534 | { return functions->IsAssignableFrom(this, clazz1, clazz2); } 535 | 536 | jobject ToReflectedField(jclass cls, jfieldID fieldID, jboolean isStatic) 537 | { return functions->ToReflectedField(this, cls, fieldID, isStatic); } 538 | 539 | jint Throw(jthrowable obj) 540 | { return functions->Throw(this, obj); } 541 | 542 | jint ThrowNew(jclass clazz, const char* message) 543 | { return functions->ThrowNew(this, clazz, message); } 544 | 545 | jthrowable ExceptionOccurred() 546 | { return functions->ExceptionOccurred(this); } 547 | 548 | void ExceptionDescribe() 549 | { functions->ExceptionDescribe(this); } 550 | 551 | void ExceptionClear() 552 | { functions->ExceptionClear(this); } 553 | 554 | void FatalError(const char* msg) 555 | { functions->FatalError(this, msg); } 556 | 557 | jint PushLocalFrame(jint capacity) 558 | { return functions->PushLocalFrame(this, capacity); } 559 | 560 | jobject PopLocalFrame(jobject result) 561 | { return functions->PopLocalFrame(this, result); } 562 | 563 | jobject NewGlobalRef(jobject obj) 564 | { return functions->NewGlobalRef(this, obj); } 565 | 566 | void DeleteGlobalRef(jobject globalRef) 567 | { functions->DeleteGlobalRef(this, globalRef); } 568 | 569 | void DeleteLocalRef(jobject localRef) 570 | { functions->DeleteLocalRef(this, localRef); } 571 | 572 | jboolean IsSameObject(jobject ref1, jobject ref2) 573 | { return functions->IsSameObject(this, ref1, ref2); } 574 | 575 | jobject NewLocalRef(jobject ref) 576 | { return functions->NewLocalRef(this, ref); } 577 | 578 | jint EnsureLocalCapacity(jint capacity) 579 | { return functions->EnsureLocalCapacity(this, capacity); } 580 | 581 | jobject AllocObject(jclass clazz) 582 | { return functions->AllocObject(this, clazz); } 583 | 584 | jobject NewObject(jclass clazz, jmethodID methodID, ...) 585 | { 586 | va_list args; 587 | va_start(args, methodID); 588 | jobject result = functions->NewObjectV(this, clazz, methodID, args); 589 | va_end(args); 590 | return result; 591 | } 592 | 593 | jobject NewObjectV(jclass clazz, jmethodID methodID, va_list args) 594 | { return functions->NewObjectV(this, clazz, methodID, args); } 595 | 596 | jobject NewObjectA(jclass clazz, jmethodID methodID, jvalue* args) 597 | { return functions->NewObjectA(this, clazz, methodID, args); } 598 | 599 | jclass GetObjectClass(jobject obj) 600 | { return functions->GetObjectClass(this, obj); } 601 | 602 | jboolean IsInstanceOf(jobject obj, jclass clazz) 603 | { return functions->IsInstanceOf(this, obj, clazz); } 604 | 605 | jmethodID GetMethodID(jclass clazz, const char* name, const char* sig) 606 | { return functions->GetMethodID(this, clazz, name, sig); } 607 | 608 | #define CALL_TYPE_METHOD(_jtype, _jname) \ 609 | __NDK_FPABI__ \ 610 | _jtype Call##_jname##Method(jobject obj, jmethodID methodID, ...) \ 611 | { \ 612 | _jtype result; \ 613 | va_list args; \ 614 | va_start(args, methodID); \ 615 | result = functions->Call##_jname##MethodV(this, obj, methodID, \ 616 | args); \ 617 | va_end(args); \ 618 | return result; \ 619 | } 620 | #define CALL_TYPE_METHODV(_jtype, _jname) \ 621 | __NDK_FPABI__ \ 622 | _jtype Call##_jname##MethodV(jobject obj, jmethodID methodID, \ 623 | va_list args) \ 624 | { return functions->Call##_jname##MethodV(this, obj, methodID, args); } 625 | #define CALL_TYPE_METHODA(_jtype, _jname) \ 626 | __NDK_FPABI__ \ 627 | _jtype Call##_jname##MethodA(jobject obj, jmethodID methodID, \ 628 | jvalue* args) \ 629 | { return functions->Call##_jname##MethodA(this, obj, methodID, args); } 630 | 631 | #define CALL_TYPE(_jtype, _jname) \ 632 | CALL_TYPE_METHOD(_jtype, _jname) \ 633 | CALL_TYPE_METHODV(_jtype, _jname) \ 634 | CALL_TYPE_METHODA(_jtype, _jname) 635 | 636 | CALL_TYPE(jobject, Object) 637 | CALL_TYPE(jboolean, Boolean) 638 | CALL_TYPE(jbyte, Byte) 639 | CALL_TYPE(jchar, Char) 640 | CALL_TYPE(jshort, Short) 641 | CALL_TYPE(jint, Int) 642 | CALL_TYPE(jlong, Long) 643 | CALL_TYPE(jfloat, Float) 644 | CALL_TYPE(jdouble, Double) 645 | 646 | void CallVoidMethod(jobject obj, jmethodID methodID, ...) 647 | { 648 | va_list args; 649 | va_start(args, methodID); 650 | functions->CallVoidMethodV(this, obj, methodID, args); 651 | va_end(args); 652 | } 653 | void CallVoidMethodV(jobject obj, jmethodID methodID, va_list args) 654 | { functions->CallVoidMethodV(this, obj, methodID, args); } 655 | void CallVoidMethodA(jobject obj, jmethodID methodID, jvalue* args) 656 | { functions->CallVoidMethodA(this, obj, methodID, args); } 657 | 658 | #define CALL_NONVIRT_TYPE_METHOD(_jtype, _jname) \ 659 | __NDK_FPABI__ \ 660 | _jtype CallNonvirtual##_jname##Method(jobject obj, jclass clazz, \ 661 | jmethodID methodID, ...) \ 662 | { \ 663 | _jtype result; \ 664 | va_list args; \ 665 | va_start(args, methodID); \ 666 | result = functions->CallNonvirtual##_jname##MethodV(this, obj, \ 667 | clazz, methodID, args); \ 668 | va_end(args); \ 669 | return result; \ 670 | } 671 | #define CALL_NONVIRT_TYPE_METHODV(_jtype, _jname) \ 672 | __NDK_FPABI__ \ 673 | _jtype CallNonvirtual##_jname##MethodV(jobject obj, jclass clazz, \ 674 | jmethodID methodID, va_list args) \ 675 | { return functions->CallNonvirtual##_jname##MethodV(this, obj, clazz, \ 676 | methodID, args); } 677 | #define CALL_NONVIRT_TYPE_METHODA(_jtype, _jname) \ 678 | __NDK_FPABI__ \ 679 | _jtype CallNonvirtual##_jname##MethodA(jobject obj, jclass clazz, \ 680 | jmethodID methodID, jvalue* args) \ 681 | { return functions->CallNonvirtual##_jname##MethodA(this, obj, clazz, \ 682 | methodID, args); } 683 | 684 | #define CALL_NONVIRT_TYPE(_jtype, _jname) \ 685 | CALL_NONVIRT_TYPE_METHOD(_jtype, _jname) \ 686 | CALL_NONVIRT_TYPE_METHODV(_jtype, _jname) \ 687 | CALL_NONVIRT_TYPE_METHODA(_jtype, _jname) 688 | 689 | CALL_NONVIRT_TYPE(jobject, Object) 690 | CALL_NONVIRT_TYPE(jboolean, Boolean) 691 | CALL_NONVIRT_TYPE(jbyte, Byte) 692 | CALL_NONVIRT_TYPE(jchar, Char) 693 | CALL_NONVIRT_TYPE(jshort, Short) 694 | CALL_NONVIRT_TYPE(jint, Int) 695 | CALL_NONVIRT_TYPE(jlong, Long) 696 | CALL_NONVIRT_TYPE(jfloat, Float) 697 | CALL_NONVIRT_TYPE(jdouble, Double) 698 | 699 | void CallNonvirtualVoidMethod(jobject obj, jclass clazz, 700 | jmethodID methodID, ...) 701 | { 702 | va_list args; 703 | va_start(args, methodID); 704 | functions->CallNonvirtualVoidMethodV(this, obj, clazz, methodID, args); 705 | va_end(args); 706 | } 707 | void CallNonvirtualVoidMethodV(jobject obj, jclass clazz, 708 | jmethodID methodID, va_list args) 709 | { functions->CallNonvirtualVoidMethodV(this, obj, clazz, methodID, args); } 710 | void CallNonvirtualVoidMethodA(jobject obj, jclass clazz, 711 | jmethodID methodID, jvalue* args) 712 | { functions->CallNonvirtualVoidMethodA(this, obj, clazz, methodID, args); } 713 | 714 | jfieldID GetFieldID(jclass clazz, const char* name, const char* sig) 715 | { return functions->GetFieldID(this, clazz, name, sig); } 716 | 717 | jobject GetObjectField(jobject obj, jfieldID fieldID) 718 | { return functions->GetObjectField(this, obj, fieldID); } 719 | jboolean GetBooleanField(jobject obj, jfieldID fieldID) 720 | { return functions->GetBooleanField(this, obj, fieldID); } 721 | jbyte GetByteField(jobject obj, jfieldID fieldID) 722 | { return functions->GetByteField(this, obj, fieldID); } 723 | jchar GetCharField(jobject obj, jfieldID fieldID) 724 | { return functions->GetCharField(this, obj, fieldID); } 725 | jshort GetShortField(jobject obj, jfieldID fieldID) 726 | { return functions->GetShortField(this, obj, fieldID); } 727 | jint GetIntField(jobject obj, jfieldID fieldID) 728 | { return functions->GetIntField(this, obj, fieldID); } 729 | jlong GetLongField(jobject obj, jfieldID fieldID) 730 | { return functions->GetLongField(this, obj, fieldID); } 731 | __NDK_FPABI__ 732 | jfloat GetFloatField(jobject obj, jfieldID fieldID) 733 | { return functions->GetFloatField(this, obj, fieldID); } 734 | __NDK_FPABI__ 735 | jdouble GetDoubleField(jobject obj, jfieldID fieldID) 736 | { return functions->GetDoubleField(this, obj, fieldID); } 737 | 738 | void SetObjectField(jobject obj, jfieldID fieldID, jobject value) 739 | { functions->SetObjectField(this, obj, fieldID, value); } 740 | void SetBooleanField(jobject obj, jfieldID fieldID, jboolean value) 741 | { functions->SetBooleanField(this, obj, fieldID, value); } 742 | void SetByteField(jobject obj, jfieldID fieldID, jbyte value) 743 | { functions->SetByteField(this, obj, fieldID, value); } 744 | void SetCharField(jobject obj, jfieldID fieldID, jchar value) 745 | { functions->SetCharField(this, obj, fieldID, value); } 746 | void SetShortField(jobject obj, jfieldID fieldID, jshort value) 747 | { functions->SetShortField(this, obj, fieldID, value); } 748 | void SetIntField(jobject obj, jfieldID fieldID, jint value) 749 | { functions->SetIntField(this, obj, fieldID, value); } 750 | void SetLongField(jobject obj, jfieldID fieldID, jlong value) 751 | { functions->SetLongField(this, obj, fieldID, value); } 752 | __NDK_FPABI__ 753 | void SetFloatField(jobject obj, jfieldID fieldID, jfloat value) 754 | { functions->SetFloatField(this, obj, fieldID, value); } 755 | __NDK_FPABI__ 756 | void SetDoubleField(jobject obj, jfieldID fieldID, jdouble value) 757 | { functions->SetDoubleField(this, obj, fieldID, value); } 758 | 759 | jmethodID GetStaticMethodID(jclass clazz, const char* name, const char* sig) 760 | { return functions->GetStaticMethodID(this, clazz, name, sig); } 761 | 762 | #define CALL_STATIC_TYPE_METHOD(_jtype, _jname) \ 763 | __NDK_FPABI__ \ 764 | _jtype CallStatic##_jname##Method(jclass clazz, jmethodID methodID, \ 765 | ...) \ 766 | { \ 767 | _jtype result; \ 768 | va_list args; \ 769 | va_start(args, methodID); \ 770 | result = functions->CallStatic##_jname##MethodV(this, clazz, \ 771 | methodID, args); \ 772 | va_end(args); \ 773 | return result; \ 774 | } 775 | #define CALL_STATIC_TYPE_METHODV(_jtype, _jname) \ 776 | __NDK_FPABI__ \ 777 | _jtype CallStatic##_jname##MethodV(jclass clazz, jmethodID methodID, \ 778 | va_list args) \ 779 | { return functions->CallStatic##_jname##MethodV(this, clazz, methodID, \ 780 | args); } 781 | #define CALL_STATIC_TYPE_METHODA(_jtype, _jname) \ 782 | __NDK_FPABI__ \ 783 | _jtype CallStatic##_jname##MethodA(jclass clazz, jmethodID methodID, \ 784 | jvalue* args) \ 785 | { return functions->CallStatic##_jname##MethodA(this, clazz, methodID, \ 786 | args); } 787 | 788 | #define CALL_STATIC_TYPE(_jtype, _jname) \ 789 | CALL_STATIC_TYPE_METHOD(_jtype, _jname) \ 790 | CALL_STATIC_TYPE_METHODV(_jtype, _jname) \ 791 | CALL_STATIC_TYPE_METHODA(_jtype, _jname) 792 | 793 | CALL_STATIC_TYPE(jobject, Object) 794 | CALL_STATIC_TYPE(jboolean, Boolean) 795 | CALL_STATIC_TYPE(jbyte, Byte) 796 | CALL_STATIC_TYPE(jchar, Char) 797 | CALL_STATIC_TYPE(jshort, Short) 798 | CALL_STATIC_TYPE(jint, Int) 799 | CALL_STATIC_TYPE(jlong, Long) 800 | CALL_STATIC_TYPE(jfloat, Float) 801 | CALL_STATIC_TYPE(jdouble, Double) 802 | 803 | void CallStaticVoidMethod(jclass clazz, jmethodID methodID, ...) 804 | { 805 | va_list args; 806 | va_start(args, methodID); 807 | functions->CallStaticVoidMethodV(this, clazz, methodID, args); 808 | va_end(args); 809 | } 810 | void CallStaticVoidMethodV(jclass clazz, jmethodID methodID, va_list args) 811 | { functions->CallStaticVoidMethodV(this, clazz, methodID, args); } 812 | void CallStaticVoidMethodA(jclass clazz, jmethodID methodID, jvalue* args) 813 | { functions->CallStaticVoidMethodA(this, clazz, methodID, args); } 814 | 815 | jfieldID GetStaticFieldID(jclass clazz, const char* name, const char* sig) 816 | { return functions->GetStaticFieldID(this, clazz, name, sig); } 817 | 818 | jobject GetStaticObjectField(jclass clazz, jfieldID fieldID) 819 | { return functions->GetStaticObjectField(this, clazz, fieldID); } 820 | jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID) 821 | { return functions->GetStaticBooleanField(this, clazz, fieldID); } 822 | jbyte GetStaticByteField(jclass clazz, jfieldID fieldID) 823 | { return functions->GetStaticByteField(this, clazz, fieldID); } 824 | jchar GetStaticCharField(jclass clazz, jfieldID fieldID) 825 | { return functions->GetStaticCharField(this, clazz, fieldID); } 826 | jshort GetStaticShortField(jclass clazz, jfieldID fieldID) 827 | { return functions->GetStaticShortField(this, clazz, fieldID); } 828 | jint GetStaticIntField(jclass clazz, jfieldID fieldID) 829 | { return functions->GetStaticIntField(this, clazz, fieldID); } 830 | jlong GetStaticLongField(jclass clazz, jfieldID fieldID) 831 | { return functions->GetStaticLongField(this, clazz, fieldID); } 832 | __NDK_FPABI__ 833 | jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID) 834 | { return functions->GetStaticFloatField(this, clazz, fieldID); } 835 | __NDK_FPABI__ 836 | jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID) 837 | { return functions->GetStaticDoubleField(this, clazz, fieldID); } 838 | 839 | void SetStaticObjectField(jclass clazz, jfieldID fieldID, jobject value) 840 | { functions->SetStaticObjectField(this, clazz, fieldID, value); } 841 | void SetStaticBooleanField(jclass clazz, jfieldID fieldID, jboolean value) 842 | { functions->SetStaticBooleanField(this, clazz, fieldID, value); } 843 | void SetStaticByteField(jclass clazz, jfieldID fieldID, jbyte value) 844 | { functions->SetStaticByteField(this, clazz, fieldID, value); } 845 | void SetStaticCharField(jclass clazz, jfieldID fieldID, jchar value) 846 | { functions->SetStaticCharField(this, clazz, fieldID, value); } 847 | void SetStaticShortField(jclass clazz, jfieldID fieldID, jshort value) 848 | { functions->SetStaticShortField(this, clazz, fieldID, value); } 849 | void SetStaticIntField(jclass clazz, jfieldID fieldID, jint value) 850 | { functions->SetStaticIntField(this, clazz, fieldID, value); } 851 | void SetStaticLongField(jclass clazz, jfieldID fieldID, jlong value) 852 | { functions->SetStaticLongField(this, clazz, fieldID, value); } 853 | __NDK_FPABI__ 854 | void SetStaticFloatField(jclass clazz, jfieldID fieldID, jfloat value) 855 | { functions->SetStaticFloatField(this, clazz, fieldID, value); } 856 | __NDK_FPABI__ 857 | void SetStaticDoubleField(jclass clazz, jfieldID fieldID, jdouble value) 858 | { functions->SetStaticDoubleField(this, clazz, fieldID, value); } 859 | 860 | jstring NewString(const jchar* unicodeChars, jsize len) 861 | { return functions->NewString(this, unicodeChars, len); } 862 | 863 | jsize GetStringLength(jstring string) 864 | { return functions->GetStringLength(this, string); } 865 | 866 | const jchar* GetStringChars(jstring string, jboolean* isCopy) 867 | { return functions->GetStringChars(this, string, isCopy); } 868 | 869 | void ReleaseStringChars(jstring string, const jchar* chars) 870 | { functions->ReleaseStringChars(this, string, chars); } 871 | 872 | jstring NewStringUTF(const char* bytes) 873 | { return functions->NewStringUTF(this, bytes); } 874 | 875 | jsize GetStringUTFLength(jstring string) 876 | { return functions->GetStringUTFLength(this, string); } 877 | 878 | const char* GetStringUTFChars(jstring string, jboolean* isCopy) 879 | { return functions->GetStringUTFChars(this, string, isCopy); } 880 | 881 | void ReleaseStringUTFChars(jstring string, const char* utf) 882 | { functions->ReleaseStringUTFChars(this, string, utf); } 883 | 884 | jsize GetArrayLength(jarray array) 885 | { return functions->GetArrayLength(this, array); } 886 | 887 | jobjectArray NewObjectArray(jsize length, jclass elementClass, 888 | jobject initialElement) 889 | { return functions->NewObjectArray(this, length, elementClass, 890 | initialElement); } 891 | 892 | jobject GetObjectArrayElement(jobjectArray array, jsize index) 893 | { return functions->GetObjectArrayElement(this, array, index); } 894 | 895 | void SetObjectArrayElement(jobjectArray array, jsize index, jobject value) 896 | { functions->SetObjectArrayElement(this, array, index, value); } 897 | 898 | jbooleanArray NewBooleanArray(jsize length) 899 | { return functions->NewBooleanArray(this, length); } 900 | jbyteArray NewByteArray(jsize length) 901 | { return functions->NewByteArray(this, length); } 902 | jcharArray NewCharArray(jsize length) 903 | { return functions->NewCharArray(this, length); } 904 | jshortArray NewShortArray(jsize length) 905 | { return functions->NewShortArray(this, length); } 906 | jintArray NewIntArray(jsize length) 907 | { return functions->NewIntArray(this, length); } 908 | jlongArray NewLongArray(jsize length) 909 | { return functions->NewLongArray(this, length); } 910 | jfloatArray NewFloatArray(jsize length) 911 | { return functions->NewFloatArray(this, length); } 912 | jdoubleArray NewDoubleArray(jsize length) 913 | { return functions->NewDoubleArray(this, length); } 914 | 915 | jboolean* GetBooleanArrayElements(jbooleanArray array, jboolean* isCopy) 916 | { return functions->GetBooleanArrayElements(this, array, isCopy); } 917 | jbyte* GetByteArrayElements(jbyteArray array, jboolean* isCopy) 918 | { return functions->GetByteArrayElements(this, array, isCopy); } 919 | jchar* GetCharArrayElements(jcharArray array, jboolean* isCopy) 920 | { return functions->GetCharArrayElements(this, array, isCopy); } 921 | jshort* GetShortArrayElements(jshortArray array, jboolean* isCopy) 922 | { return functions->GetShortArrayElements(this, array, isCopy); } 923 | jint* GetIntArrayElements(jintArray array, jboolean* isCopy) 924 | { return functions->GetIntArrayElements(this, array, isCopy); } 925 | jlong* GetLongArrayElements(jlongArray array, jboolean* isCopy) 926 | { return functions->GetLongArrayElements(this, array, isCopy); } 927 | jfloat* GetFloatArrayElements(jfloatArray array, jboolean* isCopy) 928 | { return functions->GetFloatArrayElements(this, array, isCopy); } 929 | jdouble* GetDoubleArrayElements(jdoubleArray array, jboolean* isCopy) 930 | { return functions->GetDoubleArrayElements(this, array, isCopy); } 931 | 932 | void ReleaseBooleanArrayElements(jbooleanArray array, jboolean* elems, 933 | jint mode) 934 | { functions->ReleaseBooleanArrayElements(this, array, elems, mode); } 935 | void ReleaseByteArrayElements(jbyteArray array, jbyte* elems, 936 | jint mode) 937 | { functions->ReleaseByteArrayElements(this, array, elems, mode); } 938 | void ReleaseCharArrayElements(jcharArray array, jchar* elems, 939 | jint mode) 940 | { functions->ReleaseCharArrayElements(this, array, elems, mode); } 941 | void ReleaseShortArrayElements(jshortArray array, jshort* elems, 942 | jint mode) 943 | { functions->ReleaseShortArrayElements(this, array, elems, mode); } 944 | void ReleaseIntArrayElements(jintArray array, jint* elems, 945 | jint mode) 946 | { functions->ReleaseIntArrayElements(this, array, elems, mode); } 947 | void ReleaseLongArrayElements(jlongArray array, jlong* elems, 948 | jint mode) 949 | { functions->ReleaseLongArrayElements(this, array, elems, mode); } 950 | void ReleaseFloatArrayElements(jfloatArray array, jfloat* elems, 951 | jint mode) 952 | { functions->ReleaseFloatArrayElements(this, array, elems, mode); } 953 | void ReleaseDoubleArrayElements(jdoubleArray array, jdouble* elems, 954 | jint mode) 955 | { functions->ReleaseDoubleArrayElements(this, array, elems, mode); } 956 | 957 | void GetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, 958 | jboolean* buf) 959 | { functions->GetBooleanArrayRegion(this, array, start, len, buf); } 960 | void GetByteArrayRegion(jbyteArray array, jsize start, jsize len, 961 | jbyte* buf) 962 | { functions->GetByteArrayRegion(this, array, start, len, buf); } 963 | void GetCharArrayRegion(jcharArray array, jsize start, jsize len, 964 | jchar* buf) 965 | { functions->GetCharArrayRegion(this, array, start, len, buf); } 966 | void GetShortArrayRegion(jshortArray array, jsize start, jsize len, 967 | jshort* buf) 968 | { functions->GetShortArrayRegion(this, array, start, len, buf); } 969 | void GetIntArrayRegion(jintArray array, jsize start, jsize len, 970 | jint* buf) 971 | { functions->GetIntArrayRegion(this, array, start, len, buf); } 972 | void GetLongArrayRegion(jlongArray array, jsize start, jsize len, 973 | jlong* buf) 974 | { functions->GetLongArrayRegion(this, array, start, len, buf); } 975 | void GetFloatArrayRegion(jfloatArray array, jsize start, jsize len, 976 | jfloat* buf) 977 | { functions->GetFloatArrayRegion(this, array, start, len, buf); } 978 | void GetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, 979 | jdouble* buf) 980 | { functions->GetDoubleArrayRegion(this, array, start, len, buf); } 981 | 982 | void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, 983 | const jboolean* buf) 984 | { functions->SetBooleanArrayRegion(this, array, start, len, buf); } 985 | void SetByteArrayRegion(jbyteArray array, jsize start, jsize len, 986 | const jbyte* buf) 987 | { functions->SetByteArrayRegion(this, array, start, len, buf); } 988 | void SetCharArrayRegion(jcharArray array, jsize start, jsize len, 989 | const jchar* buf) 990 | { functions->SetCharArrayRegion(this, array, start, len, buf); } 991 | void SetShortArrayRegion(jshortArray array, jsize start, jsize len, 992 | const jshort* buf) 993 | { functions->SetShortArrayRegion(this, array, start, len, buf); } 994 | void SetIntArrayRegion(jintArray array, jsize start, jsize len, 995 | const jint* buf) 996 | { functions->SetIntArrayRegion(this, array, start, len, buf); } 997 | void SetLongArrayRegion(jlongArray array, jsize start, jsize len, 998 | const jlong* buf) 999 | { functions->SetLongArrayRegion(this, array, start, len, buf); } 1000 | void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len, 1001 | const jfloat* buf) 1002 | { functions->SetFloatArrayRegion(this, array, start, len, buf); } 1003 | void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, 1004 | const jdouble* buf) 1005 | { functions->SetDoubleArrayRegion(this, array, start, len, buf); } 1006 | 1007 | jint RegisterNatives(jclass clazz, const JNINativeMethod* methods, 1008 | jint nMethods) 1009 | { return functions->RegisterNatives(this, clazz, methods, nMethods); } 1010 | 1011 | jint UnregisterNatives(jclass clazz) 1012 | { return functions->UnregisterNatives(this, clazz); } 1013 | 1014 | jint MonitorEnter(jobject obj) 1015 | { return functions->MonitorEnter(this, obj); } 1016 | 1017 | jint MonitorExit(jobject obj) 1018 | { return functions->MonitorExit(this, obj); } 1019 | 1020 | jint GetJavaVM(JavaVM** vm) 1021 | { return functions->GetJavaVM(this, vm); } 1022 | 1023 | void GetStringRegion(jstring str, jsize start, jsize len, jchar* buf) 1024 | { functions->GetStringRegion(this, str, start, len, buf); } 1025 | 1026 | void GetStringUTFRegion(jstring str, jsize start, jsize len, char* buf) 1027 | { return functions->GetStringUTFRegion(this, str, start, len, buf); } 1028 | 1029 | void* GetPrimitiveArrayCritical(jarray array, jboolean* isCopy) 1030 | { return functions->GetPrimitiveArrayCritical(this, array, isCopy); } 1031 | 1032 | void ReleasePrimitiveArrayCritical(jarray array, void* carray, jint mode) 1033 | { functions->ReleasePrimitiveArrayCritical(this, array, carray, mode); } 1034 | 1035 | const jchar* GetStringCritical(jstring string, jboolean* isCopy) 1036 | { return functions->GetStringCritical(this, string, isCopy); } 1037 | 1038 | void ReleaseStringCritical(jstring string, const jchar* carray) 1039 | { functions->ReleaseStringCritical(this, string, carray); } 1040 | 1041 | jweak NewWeakGlobalRef(jobject obj) 1042 | { return functions->NewWeakGlobalRef(this, obj); } 1043 | 1044 | void DeleteWeakGlobalRef(jweak obj) 1045 | { functions->DeleteWeakGlobalRef(this, obj); } 1046 | 1047 | jboolean ExceptionCheck() 1048 | { return functions->ExceptionCheck(this); } 1049 | 1050 | jobject NewDirectByteBuffer(void* address, jlong capacity) 1051 | { return functions->NewDirectByteBuffer(this, address, capacity); } 1052 | 1053 | void* GetDirectBufferAddress(jobject buf) 1054 | { return functions->GetDirectBufferAddress(this, buf); } 1055 | 1056 | jlong GetDirectBufferCapacity(jobject buf) 1057 | { return functions->GetDirectBufferCapacity(this, buf); } 1058 | 1059 | /* added in JNI 1.6 */ 1060 | jobjectRefType GetObjectRefType(jobject obj) 1061 | { return functions->GetObjectRefType(this, obj); } 1062 | #endif /*__cplusplus*/ 1063 | }; 1064 | 1065 | 1066 | /* 1067 | * JNI invocation interface. 1068 | */ 1069 | struct JNIInvokeInterface { 1070 | void* reserved0; 1071 | void* reserved1; 1072 | void* reserved2; 1073 | 1074 | jint (*DestroyJavaVM)(JavaVM*); 1075 | jint (*AttachCurrentThread)(JavaVM*, JNIEnv**, void*); 1076 | jint (*DetachCurrentThread)(JavaVM*); 1077 | jint (*GetEnv)(JavaVM*, void**, jint); 1078 | jint (*AttachCurrentThreadAsDaemon)(JavaVM*, JNIEnv**, void*); 1079 | }; 1080 | 1081 | /* 1082 | * C++ version. 1083 | */ 1084 | struct _JavaVM { 1085 | const struct JNIInvokeInterface* functions; 1086 | 1087 | #if defined(__cplusplus) 1088 | jint DestroyJavaVM() 1089 | { return functions->DestroyJavaVM(this); } 1090 | jint AttachCurrentThread(JNIEnv** p_env, void* thr_args) 1091 | { return functions->AttachCurrentThread(this, p_env, thr_args); } 1092 | jint DetachCurrentThread() 1093 | { return functions->DetachCurrentThread(this); } 1094 | jint GetEnv(void** env, jint version) 1095 | { return functions->GetEnv(this, env, version); } 1096 | jint AttachCurrentThreadAsDaemon(JNIEnv** p_env, void* thr_args) 1097 | { return functions->AttachCurrentThreadAsDaemon(this, p_env, thr_args); } 1098 | #endif /*__cplusplus*/ 1099 | }; 1100 | 1101 | struct JavaVMAttachArgs { 1102 | jint version; /* must be >= JNI_VERSION_1_2 */ 1103 | const char* name; /* NULL or name of thread as modified UTF-8 str */ 1104 | jobject group; /* global ref of a ThreadGroup object, or NULL */ 1105 | }; 1106 | typedef struct JavaVMAttachArgs JavaVMAttachArgs; 1107 | 1108 | /* 1109 | * JNI 1.2+ initialization. (As of 1.6, the pre-1.2 structures are no 1110 | * longer supported.) 1111 | */ 1112 | typedef struct JavaVMOption { 1113 | const char* optionString; 1114 | void* extraInfo; 1115 | } JavaVMOption; 1116 | 1117 | typedef struct JavaVMInitArgs { 1118 | jint version; /* use JNI_VERSION_1_2 or later */ 1119 | 1120 | jint nOptions; 1121 | JavaVMOption* options; 1122 | jboolean ignoreUnrecognized; 1123 | } JavaVMInitArgs; 1124 | 1125 | #ifdef __cplusplus 1126 | extern "C" { 1127 | #endif 1128 | /* 1129 | * VM initialization functions. 1130 | * 1131 | * Note these are the only symbols exported for JNI by the VM. 1132 | */ 1133 | #if 0 /* In practice, these are not exported by the NDK so don't declare them */ 1134 | jint JNI_GetDefaultJavaVMInitArgs(void*); 1135 | jint JNI_CreateJavaVM(JavaVM**, JNIEnv**, void*); 1136 | jint JNI_GetCreatedJavaVMs(JavaVM**, jsize, jsize*); 1137 | #endif 1138 | 1139 | #define JNIIMPORT 1140 | #define JNIEXPORT __attribute__ ((visibility ("default"))) 1141 | #define JNICALL __NDK_FPABI__ 1142 | 1143 | /* 1144 | * Prototypes for functions exported by loadable shared libs. These are 1145 | * called by JNI, not provided by JNI. 1146 | */ 1147 | JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved); 1148 | JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved); 1149 | 1150 | #ifdef __cplusplus 1151 | } 1152 | #endif 1153 | 1154 | 1155 | /* 1156 | * Manifest constants. 1157 | */ 1158 | #define JNI_FALSE 0 1159 | #define JNI_TRUE 1 1160 | 1161 | #define JNI_VERSION_1_1 0x00010001 1162 | #define JNI_VERSION_1_2 0x00010002 1163 | #define JNI_VERSION_1_4 0x00010004 1164 | #define JNI_VERSION_1_6 0x00010006 1165 | 1166 | #define JNI_OK (0) /* no error */ 1167 | #define JNI_ERR (-1) /* generic error */ 1168 | #define JNI_EDETACHED (-2) /* thread detached from the VM */ 1169 | #define JNI_EVERSION (-3) /* JNI version error */ 1170 | 1171 | #define JNI_COMMIT 1 /* copy content, do not free buffer */ 1172 | #define JNI_ABORT 2 /* free buffer w/o copying back */ 1173 | 1174 | #endif /* JNI_H_ */ 1175 | -------------------------------------------------------------------------------- /IDA/aarch64_func_prolog_finder.py: -------------------------------------------------------------------------------- 1 | # aarch64_func_prolog_finder.py 2 | # 3 | # Find undiscovered aarch64 functions that had been missed by IDA's auto-analysis. 4 | # 5 | # Originally from Fernand Lone Sang @ Quarkslab 6 | # https://blog.quarkslab.com/reverse-engineering-samsung-s6-sboot-part-i.html 7 | # 8 | # I've simply updated the apis for usage with 7.4.191112 9 | # diff -at- protonmail -dot- com 10 | # 11 | 12 | import idaapi 13 | 14 | def find_sig(segment, sig, callback): 15 | seg = idaapi.get_segm_by_name(segment) 16 | if not seg: 17 | return 18 | ea, maxea = seg.start_ea, seg.end_ea 19 | while ea != idaapi.BADADDR: 20 | ea = idaapi.find_binary(ea, maxea, sig, 16, idaapi.SEARCH_DOWN) 21 | if ea != idaapi.BADADDR: 22 | callback(ea) 23 | ea += 4 24 | 25 | def is_prologue_insn(ea): 26 | insn = ida_ua.insn_t() 27 | idaapi.decode_insn(insn, ea) 28 | return ida_ua.insn_t().itype in [idaapi.ARM_stp, idaapi.ARM_mov, idaapi.ARM_sub] 29 | 30 | def callback(ea): 31 | flags = ida_bytes.get_full_flags(ea) 32 | if ida_bytes.is_unknown(flags): 33 | while ea != ida_idaapi.BADADDR: 34 | if is_prologue_insn(ea - 4): 35 | ea -= 4 36 | else: 37 | print("[*] New function discovered at %#lx" % (ea)) 38 | idaapi.add_func(ea, ida_idaapi.BADADDR) 39 | break 40 | if ida_bytes.is_data(flags): 41 | print("[!] %#lx needs manual review" % (ea)) 42 | 43 | mov_x29_sp = "fd 03 00 91" 44 | find_sig("ROM", mov_x29_sp, callback) 45 | -------------------------------------------------------------------------------- /IDA/aarch64_func_prolog_finder_s9.py: -------------------------------------------------------------------------------- 1 | # aarch64_func_prolog_finder.py 2 | # 3 | # Find undiscovered aarch64 functions that had been missed by IDA's auto-analysis. 4 | # 5 | # Originally from Fernand Lone Sang @ Quarkslab 6 | # https://blog.quarkslab.com/reverse-engineering-samsung-s6-sboot-part-i.html 7 | # 8 | # I've simply updated the apis for usage with 7.4.191112 9 | # diff -at- protonmail -dot- com 10 | # 11 | 12 | import idaapi 13 | 14 | def find_sig(segment, sig, callback): 15 | seg = idaapi.get_segm_by_name(segment) 16 | if not seg: 17 | return 18 | ea, maxea = seg.start_ea, seg.end_ea 19 | while ea != idaapi.BADADDR: 20 | ea = idaapi.find_binary(ea, maxea, sig, 16, idaapi.SEARCH_DOWN) 21 | if ea != idaapi.BADADDR: 22 | callback(ea) 23 | ea += 4 24 | 25 | def is_prologue_insn(ea): 26 | insn = ida_ua.insn_t() 27 | idaapi.decode_insn(insn, ea) 28 | return ida_ua.insn_t().itype is idaapi.ARM_eor #in [idaapi.ARM_stp, idaapi.ARM_mov, idaapi.ARM_sub] 29 | 30 | def callback(ea): 31 | flags = ida_bytes.get_full_flags(ea) 32 | if ida_bytes.is_unknown(flags): 33 | while ea != ida_idaapi.BADADDR: 34 | if is_prologue_insn(ea - 8): 35 | ea -= 8 36 | else: 37 | print("[*] New function discovered at %#lx" % (ea - 8)) 38 | idaapi.add_func(ea - 8, ida_idaapi.BADADDR) 39 | break 40 | if ida_bytes.is_data(flags): 41 | print("[!] %#lx needs manual review" % (ea)) 42 | 43 | mov_x29_sp = "fd 03 00 91" 44 | find_sig("ROM", mov_x29_sp, callback) 45 | -------------------------------------------------------------------------------- /IDA/android_jni_assist.py: -------------------------------------------------------------------------------- 1 | """android_jni_assist.py: Label enums for Android JNI to aid in reversing.""" 2 | 3 | __author__ = "Tim 'diff' Strazzere" 4 | __copyright__ = "Copyright 2015, Red Naga" 5 | __license__ = "GPL" 6 | __version__ = "1.0" 7 | __email__ = "strazz@gmail.com" 8 | 9 | # Thanks to trojancyborg and TheCjw for posting code/ideas I based most of 10 | # this work on. 11 | 12 | # 13 | # Constants 14 | # 15 | DEBUG = True 16 | 17 | # TODO : There is an issue with IDA Pro where it grabs the repeatable comment 18 | # from the wrong enum if on it is performing the enum grab for the ADD 19 | # (TWO_PATTERNS) based instruction. 20 | 21 | # Attempt for the following patterns: 22 | # ADD R5, SP, #0x18+var_14 23 | # ADD R1, SP, #0x18+var_14 24 | TWO_MNEM = ['ADD'] 25 | TWO_PATTERNS = ['#0x', "+var_"] 26 | 27 | # Attempt for the following patterns: 28 | # STR R1, [SP,#0x18+var_14] 29 | # LDR R0, [SP,#0x18+var_14] 30 | THREE_MNEM = ['STR', 'LDR'] 31 | THREE_PATTERNS = ['SP'] + TWO_PATTERNS 32 | 33 | # JNI Methods to recurse through for setting enums 34 | # JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved); 35 | # JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved); 36 | # TODO : Need to find these programmatically 37 | JNI_METHODS = [ 38 | 'JNI_OnLoad', 39 | 'JNI_OnUnLoad' 40 | ] 41 | 42 | # JNI enum names and comments pulled from jni.h in the Android NDK 43 | JNIInvokeInterface = [ 44 | ('jni_DestroyJavaVM', 'jint (*DestroyJavaVM)(JavaVM*)'), 45 | ('jni_AttachCurrentThread', 'jint (*AttachCurrentThread)(JavaVM*, JNIEnv**, void*)'), 46 | ('jni_DetachCurrentThread', 'jint (*DetachCurrentThread)(JavaVM*)'), 47 | ('jni_GetEnv', 'jint (*GetEnv)(JavaVM*, void**, jint)'), 48 | ('jni_AttachCurrentThreadAsDaemon', 'jint (*AttachCurrentThreadAsDaemon)(JavaVM*, JNIEnv**, void*)') 49 | ] 50 | 51 | JNI_VERSION_MNEM = ['LDR', 'MOV'] 52 | JNI_VERSION_VALUES = ['0x10004', '0x10005', '0x10006'] 53 | 54 | JNIVersion = [ 55 | ('jni_Version_1_4' ,'JNI_VERSION_1_4'), 56 | ('jni_Version_1_5' ,'JNI_VERSION_1_5'), 57 | ('jni_Version_1_6' ,'JNI_VERSION_1_6') 58 | ] 59 | 60 | # 61 | # Utility functions 62 | # 63 | def info(formatted_string): 64 | print(formatted_string) 65 | 66 | def error(formatted_string): 67 | print('ERROR - %s' % formatted_string) 68 | 69 | def debug(formatted_string): 70 | if DEBUG: 71 | print('DEBUG - %s' % formatted_string) 72 | 73 | # 74 | # Main functionality 75 | # 76 | def create_enum(enum_name, member_infos, offset, increment): 77 | return_id = idc.add_enum(-1, enum_name, 0x1100000); 78 | 79 | if return_id == BADADDR: 80 | error('Unable to create enum : %s' % enum_name) 81 | return return_id 82 | 83 | for member_info in member_infos: 84 | debug("Attempting to create enum member and comment : %s.%s -> %s" % (enum_name, member_info[0], member_info[1])) 85 | 86 | if idc.add_enum_member(return_id, member_info[0], offset, -1) == 0: 87 | const_id = idc.get_enum_member(return_id, offset, 0, -1) 88 | 89 | if const_id == -1: 90 | debug('Unable to get constant id for : %s.%s' % (enum_name, member_info[0])) 91 | 92 | else: 93 | if ida_enum.set_enum_member_cmt(const_id, member_info[1], 1): 94 | debug('Enum value created : %s.%s' % (enum_name, member_info[0])) 95 | 96 | else: 97 | error('Enum value failed to have comment set : %s.%s' % (enum_name, member_info[0])) 98 | 99 | offset += increment 100 | else: 101 | error('Unable to create enum member : %s.%s' % (enum_name, member_info[0])) 102 | return -1 103 | 104 | info('Finished creating enum : %s' % enum_name) 105 | return return_id 106 | 107 | def create_or_find_enum(enum_name, member_infos, offset, increment): 108 | enum_id = create_enum(enum_name, member_infos, offset, increment) 109 | 110 | if enum_id == -1: 111 | debug('Unable to create enum, attempting to find one') 112 | enum_id = ida_enum.get_enum(enum_name) 113 | if enum_id == -1: 114 | error('Could create or find a enum') 115 | return False 116 | 117 | return enum_id 118 | 119 | def find_function_address(function_name): 120 | for name in Names(): 121 | if name[1] == function_name: 122 | return name[0] 123 | 124 | return -1 125 | 126 | def is_enum(addr): 127 | patterns = [] 128 | if idc.print_insn_mnem(addr) in THREE_MNEM: 129 | patterns = THREE_PATTERNS 130 | elif idc.print_insn_mnem(addr) in TWO_MNEM: 131 | patterns = TWO_PATTERNS 132 | 133 | for pattern in patterns: 134 | # This means we are in TWO_PATTERNS mode 135 | if(idc.print_operand(addr, 1) == 'SP'): 136 | if pattern in idc.print_operand(addr, 2): 137 | return True 138 | else: 139 | # THREE_PATTERNS mode 140 | if pattern in idc.print_operand(addr, 1): 141 | return True 142 | 143 | return False 144 | 145 | def mark_enums(enum_id, method): 146 | addr = find_function_address(method) 147 | if addr == -1: 148 | error('Unable to find %s' % method) 149 | return False 150 | 151 | debug('Found function starting @ 0x%x' % addr) 152 | func_end = next(Chunks(addr))[1] 153 | if(func_end < addr): 154 | error('Unable to find good function end for %s' % method) 155 | return False 156 | 157 | debug('Found function ending @ 0x%x' % func_end) 158 | 159 | while(addr < func_end): 160 | if is_enum(addr): 161 | debug('Found a enum to mark @ 0x%x' % addr) 162 | ret = idc.op_enum(addr, 1, enum_id, 0) 163 | # Try one more time due to IDA Pro bug 164 | if ret == -1: 165 | ret = idc.op_enum(addr, 1, enum_id, 0) 166 | error("Tried twice, result %s" % ret) 167 | 168 | addr = ida_search.find_code(addr, SEARCH_DOWN) 169 | 170 | return True 171 | 172 | def jni_jvm_enum_init(): 173 | jvm_enum_id = create_or_find_enum('JNI_JVM_FUNC', JNIInvokeInterface, -0x8, 0x4) 174 | 175 | if jvm_enum_id is not False: 176 | for method in JNI_METHODS: 177 | mark_enums(jvm_enum_id, method) 178 | 179 | return True 180 | 181 | def is_const(addr): 182 | # This might be incorrect to do 183 | if idc.print_insn_mnem(addr) not in JNI_VERSION_MNEM: 184 | return False 185 | 186 | for value in JNI_VERSION_VALUES: 187 | if value in idc.print_operand(addr, 1): 188 | return True 189 | 190 | return False 191 | 192 | def jni_constants(): 193 | const_enum_id = create_or_find_enum('JNI_VERSIONS', JNIVersion, 0x10004, 0x1) 194 | 195 | if const_enum_id is not False: 196 | method = 'JNI_OnLoad' 197 | addr = find_function_address(method) 198 | if addr == -1: 199 | error('Unable to find %s' % method) 200 | return False 201 | 202 | debug('Found function starting @ 0x%x' % addr) 203 | func_end = next(Chunks(addr))[1] 204 | if(func_end < addr): 205 | error('Unable to find good function end for %s' % method) 206 | return False 207 | 208 | debug('Found function ending @ 0x%x' % func_end) 209 | 210 | while(addr < func_end): 211 | if is_const(addr): 212 | debug('Found a const to mark @ 0x%x' % addr) 213 | ret = idc.op_enum(addr, 1, const_enum_id, 0) 214 | # Try one more time due to IDA Pro bug 215 | if ret == -1: 216 | ret = idc.op_enum(addr, 1, const_enum_id, 0) 217 | debug("Tried twice, result %s" % ret) 218 | 219 | addr = ida_search.find_code(addr, SEARCH_DOWN) 220 | 221 | return True 222 | 223 | def main(): 224 | jni_jvm_enum_init() 225 | jni_constants() 226 | 227 | if __name__ == "__main__": 228 | main() 229 | -------------------------------------------------------------------------------- /IDA/dalvik-rename.idc: -------------------------------------------------------------------------------- 1 | // Dalvik Function Rename Script 2 | // --- 3 | // Attempt to make the function names look better -- avoid the ugly _def_ blah crap 4 | // 5 | // Created during #Hacksgiving 2012 @Lookout 6 | // Updated 2014.2.12 to speed up and block user input to prevent issues 7 | // 8 | // Tim "diff" Strazzere 9 | // 10 | // 11 | 12 | #include 13 | 14 | static is_dalvik_function(name) 15 | { 16 | if(strstr(name, "_def_") != -1 && strstr(name, "@") != -1) { 17 | return 1; 18 | } 19 | return 0; 20 | } 21 | 22 | static strip_annoying_characters(name) { 23 | // Strip out _def_ and @ plus anthing after that 24 | name = substr(name, strstr(name, "_def_") + 5, strstr(name, "@")); 25 | 26 | // Strip trailing _ chars 27 | while(substr(name, strlen(name) - 1, -1) == "_") { 28 | name = substr(name, 0, strlen(name) - 1); 29 | } 30 | 31 | // Strip the cases of "._" inside the names 32 | if(strstr(name, "._") != -1) { 33 | name = substr(name, 0, strstr(name, "._")) + "_" + substr(name, strstr(name, "._") + 2, -1); 34 | } 35 | 36 | // Strip the cases of "__" inside the names 37 | if(strstr(name, "__") != -1) { 38 | name = substr(name, 0, strstr(name, "__")) + "_" + substr(name, strstr(name, "__") + 2, -1); 39 | } 40 | 41 | return name; 42 | } 43 | 44 | // TODO: This should just use a list and iterate through, not two hardcoded ones 45 | static get_location_by_hooks(addr) { 46 | // Mostly everything has an activity, so this should take care of 90% of the apps 47 | addr = LocByName("_def_Activity._init_@V"); 48 | if(addr == -1) { 49 | Message("Unable to find our first hook method!\n"); 50 | // Since it's possible to not have an activity, try to find the BuildConfig, which 51 | // is bundled in apps automatically by SDK 15+ 52 | addr = LocByName("_def_BuildConfig._init_@V"); 53 | if(addr == -1) { 54 | Message("Unable to find our second hook method - most likely this is going to fail now...\n"); 55 | } 56 | } 57 | } 58 | 59 | static main() { 60 | auto addr, name, new_name, new_name_with_appendable, appendable, userName, firstpass, original; 61 | firstpass = 1; 62 | 63 | addr = get_location_by_hooks(addr); 64 | 65 | SetStatus(IDA_STATUS_WORK); 66 | while(addr != -1) { 67 | name = Name(addr); 68 | userName = NameEx(BADADDR, addr); 69 | if(name != "") { 70 | if(name != userName) { 71 | Message("Detected a user defined name of [ %s ] will no overwrite!\n", userName); 72 | } else { 73 | if(is_dalvik_function(name)) { 74 | appendable = 0; 75 | new_name = new_name_with_appendable = strip_annoying_characters(name); 76 | // Loop through a few tries incase the name already exists 77 | while(!MakeNameEx(addr, new_name_with_appendable, 0)) { 78 | new_name_with_appendable = new_name + sprintf("_%i", appendable); 79 | appendable++; 80 | } 81 | } 82 | } 83 | } 84 | if(firstpass) { 85 | original = addr; 86 | addr = NextAddr(addr); 87 | if(addr == -1) { 88 | firstpass = 0; 89 | } 90 | } else { 91 | original = PrevAddr(original); 92 | addr = original; 93 | } 94 | } 95 | SetStatus(IDA_STATUS_READY); 96 | } -------------------------------------------------------------------------------- /IDA/dbg_dalvik.cfg: -------------------------------------------------------------------------------- 1 | // 2 | // This is IDA Dalvik debugger configuration file 3 | // This file contains the default configuration 4 | // 5 | 6 | // Path to Android Debug Bridge (adb) executable. 7 | // IDA does the best efforts to locate it. 8 | ADB_PATH = "$ANDROID_SDK_ROOT/platform-tools/adb"; 9 | 10 | // Direct an adb command a specific emulator/device instance, for example "emulator-5554" 11 | // DEVSERNUM = 12 | 13 | // Unique name for the package, for example "com.google.app.appname" 14 | // PACKAGE = 15 | 16 | // Name of the class implementing the activity, for example ".MyActivity" 17 | // ACTIVITY = 18 | 19 | // Wait for application start before check for it readiness (msecs) 20 | ADB_LAUNCH_TIMEOUT = 1000 21 | 22 | // Number of wait cycles 23 | ADB_LAUNCH_COUNT = 40 24 | 25 | // Debug: number of bytes from adb tcp package to dump 26 | ADB_MAX_DUMP_LEN = 32 27 | 28 | // Wait for adb client to perform its task 29 | ADB_CLIENT_TIMEOUT = 5000 30 | 31 | // Show hexadecimal object IDs in Locals/Watches windows 32 | SHOW_OBJECTID = NO 33 | 34 | // Safe mode: prefetch object ID as int64 and check it before dereferencing 35 | SAFEMODE = YES 36 | 37 | // Set breakpoints at the all methods of the activity class 38 | PRESETBPTS = NO -------------------------------------------------------------------------------- /IDA/ida_color_schema.clr: -------------------------------------------------------------------------------- 1 | [DISASM] 2 | 000000 //Instruction 3 | aaaaaa //Directive 4 | f3c5ff //Macro name 5 | 7e6082 //Register name 6 | 666666 //Other keywords 7 | ffffff //Dummy data name 8 | b9ebeb //Dummy code name 9 | b9ebeb //Dummy unexplored name 10 | bbecff //Hidden name 11 | c0c0c0 //Library function name 12 | 00d269 //Local variable name 13 | 00ff00 //Regular data name 14 | 3250d2 //Regular code name 15 | 4646ff //Regular unexplored name 16 | 7faaff //Demangled name 17 | 617c7c //Segment name 18 | 3250d2 //Imported name 19 | 008080 //Suspicious constant 20 | 3734ff //Char in instruction 21 | c0c0c0 //String in instruction 22 | 595959 //Number in instruction 23 | f3c5ff //Char in data 24 | ffaaff //String in data 25 | 00d2ff //Number in data 26 | ffff00 //Code reference 27 | 0080ff //Data reference 28 | 00d2ff //Code reference to tail 29 | 00d69d //Data reference to tail 30 | 7e07df //Automatic comment 31 | 00d269 //Regular comment 32 | 00f379 //Repeatable comment 33 | 3250d2 //Extra line 34 | ababab //Collapsed line 35 | adad73 //Line prefix: library function 36 | fd5aff //Line prefix: regular function 37 | 7fffff //Line prefix: instruction 38 | 00ffaa //Line prefix: data 39 | 00d2ff //Line prefix: unexplored 40 | ffaaff //Line prefix: externs 41 | 00ffff //Line prefix: current item 42 | 000000 //Line prefix: current line 43 | 2d2d2d //Punctuation 44 | 32ade1 //Opcode bytes 45 | ffff00 //Manual operand 46 | 666666 //Error 47 | 0000aa //Default color 48 | 617c7c //Selected 49 | 009d9d //Library function 50 | ff55ff //Regular function 51 | 000000 //Single instruction 52 | 00aaff //Data bytes 53 | 000000 //Unexplored byte 54 | [NAVBAR] 55 | ffaa00 //Library function 56 | 00aaff //Regular function 57 | 000080 //Instruction 58 | b9ebeb //Data item 59 | 007878 //Unexplored 60 | ff00ff //External symbol 61 | 0000ca //Errors 62 | 4a4a4a //Gaps 63 | 00ff80 //Cursor 64 | 0080ff //Address 65 | [DEBUG] 66 | ffd060 //Current IP 67 | ffa0a0 //Current IP (Enabled) 68 | 408020 //Current IP (Disabled) 69 | 050000 //Current IP (Unavailible) 70 | 0000ff //Address 71 | 00ff00 //Address (Enabled) 72 | 004080 //Address (Disabled) 73 | 0080ff //Address (Unavailible) 74 | ececec //Registers 75 | ff0000 //Registers (Changed) 76 | 800080 //Registers (Edited) 77 | [ARROW] 78 | 34466c //Jump in current function 79 | e2e200 //Jump external to function 80 | 00aaff //Jump under the cursor 81 | 008000 //Jump target 82 | ff4040 //Register target 83 | [GRAPH] 84 | b2b2b2 //Top color 85 | b2b2b2 //Bottom color 86 | f5f5f5 //Normal title 87 | e2e2e2 //Selected title 88 | 54585e //Current title 89 | 00ffff //Group frame 90 | 242424 //Node shadow 91 | 003900 //Highlight color 1 92 | 00006d //Highlight color 2 93 | 0000ff //Foreign node 94 | cb4300 //Normal edge 95 | 009100 //Yes edge 96 | 0000bc //No edge 97 | ffaaaa //Highlighted edge 98 | 008ec6 //Current edge 99 | [MISC] 100 | 212121 //Message text 101 | d4d4d4 //Message background 102 | 404080 //Patched bytes 103 | 0080ff //Unsaved changes 104 | -------------------------------------------------------------------------------- /IDA/import_kallsyms.py: -------------------------------------------------------------------------------- 1 | import ida_funcs 2 | import ida_name 3 | 4 | def do_rename(line): 5 | symbol_address, symbol_type, symbol_name = line.strip().split(' ') 6 | if symbol_type in ('t', 'T'): 7 | ida_funcs.add_func(int(symbol_address, 16)) 8 | attempts = 0 9 | while attempts < 10: 10 | if attempts > 0: 11 | symbol_name = ('%s_%d' % (symbol_name[:-2], attempts)) 12 | if ida_name.set_name(int(symbol_address, 16), symbol_name): 13 | break 14 | else: 15 | attempts += 1 16 | 17 | ### do_rename(line): 18 | 19 | if __name__ == "__main__": 20 | with open('/home/diff/path/to/the.kallsyms', 'r') as file_handle: 21 | for line in file_handle: 22 | do_rename(line) 23 | 24 | -------------------------------------------------------------------------------- /IDA/jaigu_assist.py: -------------------------------------------------------------------------------- 1 | """jaigu_assist.py: Label function wrappers used by jaigu.""" 2 | 3 | __author__ = "Tim 'diff' Strazzere" 4 | __copyright__ = "Copyright 2018, Red Naga" 5 | __license__ = "GPL" 6 | __version__ = "1.0" 7 | __email__ = "strazz@gmail.com" 8 | 9 | # 10 | # Constants 11 | # 12 | DEBUG = False 13 | 14 | # Attempt for the following pattern 15 | # LOAD:00027DEC sub_27DEC ; CODE XREF: sub_CE58+1D4↑p 16 | # LOAD:00027DEC ; sub_DCAC+1A↑p 17 | # LOAD:00027DEC BX PC 18 | # LOAD:00027DEC ; --------------------------------------------------------------------------- 19 | # LOAD:00027DEE ALIGN 0x10 20 | # LOAD:00027DF0 CODE32 21 | # LOAD:00027DF0 22 | # LOAD:00027DF0 loc_27DF0 ; CODE XREF: sub_27DEC↑j 23 | # LOAD:00027DF0 LDR R12, =(__fixdfsi - 0x27DFC) 24 | # LOAD:00027DF4 ADD PC, R12, PC ; __fixdfsi 25 | # LOAD:00027DF4 ; End of function sub_27DEC 26 | # 27 | # Above should be renamed to "fixdfsi_wrapper" (dropping the leading '_'s) 28 | 29 | 30 | # 31 | # Utility functions 32 | # 33 | def info(formatted_string): 34 | print formatted_string 35 | 36 | def error(formatted_string): 37 | print 'ERROR - %s' % formatted_string 38 | 39 | def debug(formatted_string): 40 | if DEBUG: 41 | print 'DEBUG - %s' % formatted_string 42 | 43 | # 44 | # Main functionality 45 | # 46 | 47 | def find_str(s, char): 48 | index = 0 49 | 50 | if char in s: 51 | c = char[0] 52 | for ch in s: 53 | if ch == c: 54 | if s[index:index+len(char)] == char: 55 | return index 56 | 57 | index += 1 58 | 59 | return -1 60 | 61 | def find_space(s): 62 | return find_str(s, ' ') 63 | 64 | def trim_underscore(s): 65 | if s.startswith('_'): 66 | return trim_underscore(s[1:]) 67 | return s 68 | 69 | def main(): 70 | load_seg = idaapi.get_segm_by_name('LOAD') 71 | for addr in Functions(load_seg.startEA, load_seg.endEA): 72 | name = GetFunctionName(addr) 73 | func = idaapi.get_func(addr) 74 | if name.startswith('sub_'): 75 | debug('Looking at %s @ 0x%x' % (name, addr)) 76 | # Starts with 'BX PC' ? 77 | if GetMnem(addr) == 'BX' and GetOpnd(addr, 0) == 'PC': 78 | addr = FindCode(addr, SEARCH_DOWN) 79 | if GetMnem(addr) == 'LDR' and GetOpnd(addr, 0) == 'R12' and GetOpnd(addr, 1).startswith('=('): 80 | real_name = GetOpnd(addr, 1) 81 | real_name = trim_underscore(real_name[2:find_space(real_name)]) 82 | debug('%s real name should be %s_wrapper' % (name, real_name)) 83 | 84 | if idc.MakeNameEx(func.startEA, real_name, SN_PUBLIC): 85 | info('%s renamed to %s_wrapper' % (name, real_name)) 86 | else: 87 | debug('Skipping %s' % name) 88 | 89 | if __name__ == "__main__": 90 | main() 91 | -------------------------------------------------------------------------------- /IDA/raxir_decrypter.py: -------------------------------------------------------------------------------- 1 | """decrypter.py: Automate some reversing of some Dalvik encryption for Raxir surveillance implants.""" 2 | 3 | __author__ = "Tim 'diff' Strazzere" 4 | __copyright__ = "Copyright 2016, Red Naga" 5 | __license__ = "GPL" 6 | __version__ = "1.0" 7 | __email__ = ["strazz@gmail.com"] 8 | 9 | from idautils import * 10 | from idc import * 11 | import idaapi 12 | import sys 13 | import string 14 | 15 | # 16 | # Constants 17 | # 18 | DEBUG = False 19 | 20 | # 21 | # Utility functions 22 | # 23 | def info(formatted_string): 24 | print formatted_string 25 | 26 | def error(formatted_string): 27 | print 'ERROR - %s' % formatted_string 28 | 29 | def debug(formatted_string): 30 | if DEBUG: 31 | print 'DEBUG - %s' % formatted_string 32 | 33 | def readShort(addr): 34 | return (GetOriginalByte(addr + 0x1) << 0x8) + GetOriginalByte(addr) 35 | 36 | def readInt(addr): 37 | return (GetOriginalByte(addr + 0x3) << 0x18) + (GetOriginalByte(addr + 0x2) << 0x10) + (GetOriginalByte(addr + 0x1) << 0x8) + GetOriginalByte(addr) 38 | 39 | # Todo this will only accept strings of lenght 0xFF 40 | def getStringFromAddr(addr): 41 | length = GetOriginalByte(addr) 42 | string = '' 43 | for i in range(1, length + 1): 44 | string = '%s%c' % (string, unichr(GetOriginalByte(addr + i))) 45 | 46 | return string 47 | 48 | def getString(addr): 49 | string_id = readShort(addr + 0x2) # (GetOriginalByte(addr + 0x3) << 0x8) + GetOriginalByte(addr + 0x2) 50 | string_ids = ida_segment.get_segm_by_name('STR_IDS') 51 | string_addr = readInt(string_ids.startEA + (string_id * 4)) 52 | 53 | return getStringFromAddr(string_addr) 54 | 55 | def generic_decrypt(encrypted, mod, static_xor, mod_add_1, mod_add_2): 56 | if encrypted is None or mod is None: 57 | return '' 58 | 59 | mod = mod + mod_add_1 60 | 61 | out = '' 62 | for char in list(encrypted): 63 | out = '%s%s' % (out, unichr(ord(char) ^ (mod & static_xor))) 64 | mod = (mod + mod_add_2) 65 | 66 | # MakeComm and MakeRptCmt barf if we don't convert this to non-unicode, unknown if this will cause issues downstream... 67 | return out.encode('ascii', 'replace')#.encode('UTF-32') 68 | 69 | cryptions = [ 70 | # v 7.0.0 obf 71 | [ 'Gson.equals(ref, int)', 0x5F, -0xC, 0x3 ], 72 | [ 'g9.concat(int, ref)', 0x5F, 0xB, -0xB ], 73 | [ 'Autostart.regionMatches(int, ref)', 0x5F, 0xE, -0xB ], 74 | [ 'f.replace(ref, int)', 0x5F, 0xD, 0xB ], 75 | [ 'h.equals(ref, int)', 0x5F, 0xC, 0x9 ], 76 | [ 'a.toString(int, ref)', 0x5F, -0xB, -0x1 ], 77 | # Earlier samples - v 4.0 obf 78 | [ 'Gson.getChars(ref, int)', 0x5F, 0x7, 0xD ], 79 | [ 'JsonNull.split(int, ref)', 0x5F, 0x8, 0xF ], 80 | # v 4.0 obf 81 | [ 'JsonNull.concat(int, ref)', 0x5F, -0x7, 0x9 ], 82 | [ 'Gson.indexOf(ref, int)', 0x5F, 0x3, -0xD ], 83 | # v 6.1.0 obf - tre 84 | [ 'li.valueOf(int, ref)', 0x5F, 0xF, -0x1 ], 85 | [ 'Gson.concat(ref, int)', 0x5f, -0x1, 0x1 ], 86 | # Zed detect sample - v 6.1.0 obf - bulk 87 | # [ 'Gson.indexOf(ref, int)', 0x5F, 0x5, -0x9 ], 88 | [ 'JsonNull.startsWith(int, ref)', 0x5F, -0x5, -0xB ], 89 | # v 3.2 obf 90 | [ 'Gson.endsWith(int, ref)', 0x5F, 0x1, -0x9 ], 91 | [ 'k9.toString(ref, int)', 0x5F, -0xA, 0x9 ], 92 | ] 93 | 94 | cryptions_3arg = [ 95 | [ 'e.getChars(ref, int, int)', 0x5F, -0xF ], 96 | ] 97 | 98 | def is_encrypted(addr): 99 | if GetMnem(addr) == 'const-string': 100 | addr_2 = FindCode(addr, SEARCH_DOWN) 101 | if 'const/' in GetMnem(addr_2): 102 | addr_3 = FindCode(addr_2, SEARCH_DOWN) 103 | if GetMnem(addr_3) == 'invoke-static': 104 | for (func, xor, mod1, mod2) in cryptions: 105 | if func in GetOpnd(addr_3, 2): 106 | debug(' %s in %s ' % (func, GetOpnd(addr_3, 2))) 107 | # GetOpnd(addr, 2) will just return the string name, so, we're screwed and need to calculate it by hand 108 | # This is done by getting the string_id offset, then looking it up in the STR_ID table... 109 | loaded_string = getString(addr) 110 | # Should always work, it will guess that it's base16 and chop off the expected '0x' prefix 111 | modifier = int(GetOpnd(addr_2, 1), 0) 112 | info('0x%x : %s' % (addr, generic_decrypt(loaded_string, modifier, xor, mod1, mod2))) 113 | MakeComm(addr, generic_decrypt(loaded_string, modifier, xor, mod1, mod2)) 114 | return True 115 | elif 'const/' in GetMnem(addr_3): 116 | addr_4 = FindCode(addr_3, SEARCH_DOWN) 117 | if GetMnem(addr_4) == 'invoke-static': 118 | for (func, xor, mod1) in cryptions_3arg: 119 | if func in GetOpnd(addr_4, 3): 120 | debug(' %s in %s ' % (func, GetOpnd(addr_4, 3))) 121 | loaded_string = getString(addr) 122 | modifier = int(GetOpnd(addr_2, 1), 0) 123 | mod2 = int(GetOpnd(addr_3, 1), 0) 124 | info('0x%x : %s' % (addr, generic_decrypt(loaded_string, modifier, xor, mod1, mod2))) 125 | MakeComm(addr, generic_decrypt(loaded_string, modifier, xor, mod1, mod2)) 126 | return True 127 | elif 'const/' in GetMnem(addr): 128 | addr_2 = FindCode(addr, SEARCH_DOWN) 129 | if GetMnem(addr_2) == 'const-string': 130 | addr_3 = FindCode(addr_2, SEARCH_DOWN) 131 | if GetMnem(addr_3) == 'invoke-static': 132 | for (func, xor, mod1, mod2) in cryptions: 133 | if func in GetOpnd(addr_3, 2): 134 | debug(' %s in %s ' % (func, GetOpnd(addr_3, 2))) 135 | modifier = int(GetOpnd(addr, 1), 0) 136 | loaded_string = getString(addr_2) 137 | info('0x%x : %s' % (addr, generic_decrypt(loaded_string, modifier, xor, mod1, mod2))) 138 | MakeComm(addr, ('%s' % generic_decrypt(loaded_string, modifier, xor, mod1, mod2))) 139 | return True 140 | return False 141 | 142 | def main(): 143 | strings_added = 0 144 | code_seg = ida_segment.get_segm_by_name('CODE') 145 | 146 | for addr in Functions(code_seg.startEA, code_seg.endEA): 147 | name = GetFunctionName(addr) 148 | 149 | end_addr = Chunks(addr).next()[1] 150 | if(end_addr < addr): 151 | error('Unable to find good end for the function %s' % name) 152 | pass 153 | 154 | debug('Found function %s starting/ending @ 0x%x 0x%x' % (name, addr, end_addr)) 155 | 156 | while addr <= end_addr: 157 | if is_encrypted(addr): 158 | strings_added += 1 159 | 160 | addr = FindCode(FindCode(FindCode(addr, SEARCH_DOWN), SEARCH_DOWN), SEARCH_DOWN) 161 | else: 162 | addr = FindCode(addr, SEARCH_DOWN) 163 | 164 | info('%d strings decrypted' % strings_added) 165 | 166 | if __name__ == "__main__": 167 | info('Dalvik Decryptor loaded...') 168 | main() -------------------------------------------------------------------------------- /IDA/xorish.py: -------------------------------------------------------------------------------- 1 | # xorish.py 2 | # 3 | # Just playing around with fast and easy commenting for 4 | # IDA Pro, mainly used on some ELF ARM binaries 5 | # 6 | # Tim Strazzere 7 | # 8 | 9 | def strxor(a, b): 10 | return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a, b*100)]) 11 | 12 | def xor(): 13 | print ' ..' 14 | ea = ScreenEA() 15 | string = idc.GetString(idc.GetOperandValue(ea,1)) 16 | key = 'BB2FA36AAA9541F0' 17 | xored_string = strxor(string, key) 18 | print ' got %s ' % xored_string 19 | comment = '' 20 | if GetCommentEx(ea, 1) is not None: 21 | comment = idc.GetCommentEx(ea, 1) + '\n' 22 | MakeRptCmt(ea, comment + string + " xor'ed " + xored_string) 23 | 24 | # Create something bindable 25 | idaapi.CompileLine('static xorish() { RunPythonStatement("xor()"); }') 26 | # Bind the hotkey 27 | AddHotkey("/", 'xorish') 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | android-scripts 2 | =============== 3 | 4 | Collection of Android reverse engineering scripts that make my life easier 5 | 6 | Directories; 7 | - IDA - Contains IDC/python scripts 8 | - Decoders - Contains decoders (often written in ruby) for malware 9 | - file - Contains proper filetyping for Android files using the 'file' command 10 | - shell - Contains scripts to be used via bash shell -------------------------------------------------------------------------------- /file/java: -------------------------------------------------------------------------------- 1 | 2 | #------------------------------------------------------------ 3 | # $File: java,v 1.14 2013/02/08 16:54:45 christos Exp $ 4 | # Java ByteCode and Mach-O binaries (e.g., Mac OS X) use the 5 | # same magic number, 0xcafebabe, so they are both handled 6 | # in the entry called "cafebabe". 7 | #------------------------------------------------------------ 8 | # Java serialization 9 | # From Martin Pool (m.pool@pharos.com.au) 10 | 0 beshort 0xaced Java serialization data 11 | >2 beshort >0x0004 \b, version %d 12 | 13 | 0 belong 0xfeedfeed Java KeyStore 14 | !:mime application/x-java-keystore 15 | 0 belong 0xcececece Java JCE KeyStore 16 | !:mime application/x-java-jce-keystore 17 | 18 | # Dalvik .dex format. http://retrodev.com/android/dexformat.html 19 | # From "Mike Fleming" 20 | # Fixed to avoid regexec 17 errors on some dex files 21 | # From "Tim Strazzere" 22 | 0 string dex\n 23 | >0 regex dex\n[0-9]{2}\0 Dalvik dex file 24 | >4 string >000 version %s 25 | 0 string dey\n 26 | >0 regex dey\n[0-9]{2}\0 Dalvik dex file (optimized for host) 27 | >4 string >000 version %s 28 | 29 | # Java source 30 | 0 regex ^import.*;$ Java source 31 | !:mime text/x-java 32 | 33 | # http://android.stackexchange.com/questions/23357/\ 34 | # is-there-a-way-to-look-inside-and-modify-an-adb-backup-created-file/\ 35 | # 23608#23608 36 | 0 string ANDROID\040BACKUP\n Android Backup 37 | >15 string 1\n \b, version 1 38 | >17 string 0\n \b, uncompressed 39 | >17 string 1\n \b, compressed 40 | >19 string none\n \b, unencrypted 41 | >19 string AES-256\n \b, encrypted AES-256 42 | 43 | # Android zImage boot/recovery Images 44 | # File format found here: ttps://github.com/android/platform_system_core/blob/master/mkbootimg/bootimg.h 45 | # From "Tim Strazzere" 46 | 0 string ANDROID! Android Boot/Recovery zImage 47 | 48 | # Below two files are of Android Resource types, always should begin with the resource 49 | # chunk header identifying their types (table/xml) with a set size 50 | # From "Tim Strazzere" 51 | # Android Compiled Resources File (.arsc) 52 | 0 belong 0x02000c00 Android Compiled Resources 53 | # Android Compiled XML (Manifest) File 54 | 0 belong 0x03000800 Android Compiled XML -------------------------------------------------------------------------------- /shell/batch-baksmali: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Because nothing now a days have one dex file, 4 | # and I'm tired to telling baksmali all the files 5 | # while trying to keep them in seperate dirs... 6 | # 7 | # diff@protonmail.com 8 | 9 | classes=() 10 | outdir="" 11 | 12 | previous="" 13 | for arg in $@ 14 | do 15 | if [[ "${arg}" == *.dex ]] 16 | then 17 | classes+=("${arg}") 18 | fi 19 | 20 | if [[ "$previous" == "-o" ]] 21 | then 22 | outdir="${arg}" 23 | fi 24 | previous="${arg}" 25 | done 26 | 27 | if [ -z "$outdir" ] 28 | then 29 | outdir="out" 30 | fi 31 | 32 | $(mkdir -p $outdir) 33 | 34 | for dex in "${classes[@]}" 35 | do 36 | dex_dir=${dex//[\.]/_} 37 | baksmali d "${dex}" -o "${outdir}/${dex_dir}" 38 | done 39 | -------------------------------------------------------------------------------- /shell/ida_android: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Currently in IDA Pro 6.6.140605 there is an issue where the 4 | # Dalvik debugger (JDWP) will assign the local port to the android_server 5 | # default (2346) - meaning if you attempt to do the normal forward of the 6 | # remote port 2346 to the local port, it will collide and one will die. 7 | # There is no actual input for changing the forward on the JDWP port currently 8 | # so I suggest changing your default android_server remote port here. 9 | # 10 | 11 | start_android_server() { 12 | adb shell "su sh /data/local/tmp/android_server -p$PORT" & 13 | } 14 | 15 | forward_tcp() { 16 | adb forward tcp:$PORT tcp:$PORT 17 | } 18 | 19 | PORT=2346 20 | if [ $# -gt 0 ] 21 | then 22 | if [[ $1 == -p* ]] 23 | then 24 | PORT=${1:2} 25 | fi 26 | fi 27 | 28 | echo 'Attempting to bind and forward port $PORT' 29 | 30 | start_android_server $PORT 31 | forward_tcp $PORT -------------------------------------------------------------------------------- /shell/int_strings: -------------------------------------------------------------------------------- 1 | grep -ir "const-string" $1 | grep "\\\u" | cut -d'"' -f2 | sort | uniq -------------------------------------------------------------------------------- /shell/pullapk: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | adb shell pm path $1 |\ 4 | sed 's/package://' |\ 5 | tr -d '\r' |\ 6 | xargs -I % adb pull % $1.apk -------------------------------------------------------------------------------- /shell/wrapapk: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Tired of fixing the long package names for doing LD_PRELOAD 4 | # hacks so this will automatically trip and set the property 5 | # 6 | # Assumes there is only one device connect to adb and you have 7 | # shell -- uses "su sh" since just "su" causes a failure on 8 | # real devices for me 9 | 10 | KEY=$1 11 | VALUE=$2 12 | 13 | trim_key() { 14 | echo $(echo -n "wrap.$KEY" | cut -c1-31) 15 | } 16 | 17 | echo $(adb shell su sh setprop $(trim_key) $VALUE) --------------------------------------------------------------------------------