public static bool[] makeSkipDataByCode(byte[] need) { DisassemblerTrumb Disassembler = new DisassemblerTrumb(); DisassemblerTrumb.VM vm = new DisassemblerTrumb.VM(); uint length = (uint)need.Length; bool isFunctionEnd = false; uint ldrCount = 0; bool[] isSkip = new bool[U.Padding4(length)]; for (uint i = 0; i < length - 3;) { if (isFunctionEnd) { //関数は抜けてしまったので、ldr用のポインタだけを見る. if (ldrCount <= 0) { //LDR値の地帯を抜けたので次はまた関数に復帰するはず. isFunctionEnd = false; continue; } ldrCount--; if (U.isPointer(U.u32(need, i))) { isSkip[i + 0] = true; isSkip[i + 1] = true; isSkip[i + 2] = true; isSkip[i + 3] = true; } i += 4; continue; } DisassemblerTrumb.Code code = Disassembler.Disassembler(need, i, length, vm); if (code.Type == DisassemblerTrumb.CodeType.CALL) {//関数呼び出しはアドレスの違いがかなり出てくるので. isSkip[i + 0] = true; isSkip[i + 1] = true; isSkip[i + 2] = true; isSkip[i + 3] = true; } if (code.Type == DisassemblerTrumb.CodeType.LDR) { //LDRで超長距離飛んでしまう場合は例外. uint a = U.u16(need, i); uint imm = DisassemblerTrumb.LDR_IMM(a); if (imm >= 0x64) {//あまりに長い距離飛ぶ場合、シリーズ間でずれることがあるらしい 0x64は適当な値です. isSkip[i + 0] = true; isSkip[i + 1] = true; isSkip[i + 2] = true; //長距離LDRをした次の命令も変わることがあるらしいので、ねんのため isSkip[i + 3] = true; } else { isSkip[i + 0] = true; //次の関数の開始位置を推測. BXJMPで抜けた後 LDRデータが終わったら、次の関数があるはず. ldrCount++; } } i += code.GetLength(); if (code.Type == DisassemblerTrumb.CodeType.BXJMP) {//関数終端 以降あるのは ldr用のアドレス地帯だろう isFunctionEnd = true; //関数を抜けたときに 4バイトパディングを維持しないといけない. i = U.Padding4(i); } } return(isSkip); }