public bool decrypt(PeImage peImage, ref DumpedMethods dumpedMethods) { dumpedMethods = new DumpedMethods(); bool decrypted = false; var metadataTables = peImage.Cor20Header.createMetadataTables(); var methodDef = metadataTables.getMetadataType(MetadataIndex.iMethodDef); uint methodDefOffset = methodDef.fileOffset; for (int i = 0; i < methodDef.rows; i++, methodDefOffset += methodDef.totalSize) { uint bodyRva = peImage.offsetReadUInt32(methodDefOffset); if (bodyRva == 0) continue; uint bodyOffset = peImage.rvaToOffset(bodyRva); var dm = new DumpedMethod(); dm.token = (uint)(0x06000001 + i); byte[] code, extraSections; peImage.Reader.BaseStream.Position = bodyOffset; var mbHeader = MethodBodyParser.parseMethodBody(peImage.Reader, out code, out extraSections); if (code.Length < 6 || code[0] != 0x2A || code[1] != 0x2A) continue; dm.code = code; dm.extraSections = extraSections; int seed = BitConverter.ToInt32(code, 2); Array.Copy(newCodeHeader, code, newCodeHeader.Length); if (seed == 0) decrypt(code); else decrypt(code, seed); dm.mdImplFlags = peImage.offsetReadUInt16(methodDefOffset + (uint)methodDef.fields[1].offset); dm.mdFlags = peImage.offsetReadUInt16(methodDefOffset + (uint)methodDef.fields[2].offset); dm.mdName = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[3].offset, methodDef.fields[3].size); dm.mdSignature = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[4].offset, methodDef.fields[4].size); dm.mdParamList = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[5].offset, methodDef.fields[5].size); dm.mhFlags = mbHeader.flags; dm.mhMaxStack = mbHeader.maxStack; dm.mhCodeSize = (uint)dm.code.Length; dm.mhLocalVarSigTok = mbHeader.localVarSigTok; dumpedMethods.add(dm); decrypted = true; } return decrypted; }
public DecrypterBase(PeImage peImage, CodeHeader codeHeader) { this.peImage = peImage; this.codeHeader = codeHeader; endOfMetadata = peImage.rvaToOffset(peImage.Cor20Header.metadataDirectory.virtualAddress + peImage.Cor20Header.metadataDirectory.size); }
public MethodInfos(MainType mainType, PeImage peImage, PeHeader peHeader, McKey mcKey) { this.mainType = mainType; this.peImage = peImage; this.peHeader = peHeader; this.mcKey = mcKey; structSize = getStructSize(mcKey); uint methodInfosRva = peHeader.getRva2(0x0FF8, mcKey.readUInt32(0x005A)); uint encryptedDataRva = peHeader.getRva2(0x0FF0, mcKey.readUInt32(0x0046)); methodInfosOffset = peImage.rvaToOffset(methodInfosRva); encryptedDataOffset = peImage.rvaToOffset(encryptedDataRva); }
static uint getOldCodeHeaderOffset(PeImage peImage) { var sect = getLastOf(peImage, sections); if (sect == null || sect.virtualSize < 0x100) return 0; return peImage.rvaToOffset(sect.virtualAddress + sect.virtualSize - 0x100); }
static uint getCodeHeaderOffset(PeImage peImage) { return peImage.rvaToOffset(peImage.Cor20Header.metadataDirectory.virtualAddress + peImage.Cor20Header.metadataDirectory.size); }
public MethodInfos(MainType mainType, PeImage peImage, PeHeader peHeader, McKey mcKey) { this.mainType = mainType; this.peImage = peImage; this.peHeader = peHeader; this.mcKey = mcKey; decryptHandlersV1 = new Decrypt[] { decrypt1a, decrypt4a, decrypt2a, decrypt3a, decrypt5, decrypt6, decrypt7 }; decryptHandlersV2 = new Decrypt[] { decrypt3a, decrypt2a, decrypt1a, decrypt4a, decrypt5, decrypt6, decrypt7 }; decryptHandlersV3 = new Decrypt[] { decrypt1a, decrypt2a, decrypt3a, decrypt4a, decrypt5, decrypt6, decrypt7 }; decryptHandlersV4 = new Decrypt[] { decrypt2a, decrypt1a, decrypt3a, decrypt4a, decrypt5, decrypt6, decrypt7 }; decryptHandlersV5a = new Decrypt[] { decrypt4a, decrypt2a, decrypt3a, decrypt1a, decrypt5, decrypt6, decrypt7 }; decryptHandlersV5b = new Decrypt[] { decrypt4b, decrypt2b, decrypt3b, decrypt1b, decrypt6, decrypt7, decrypt5 }; decryptHandlersV5c = new Decrypt[] { decrypt4c, decrypt2c, decrypt3c, decrypt1c, decrypt6, decrypt7, decrypt5 }; structSize = getStructSize(mcKey); uint methodInfosRva = peHeader.getRva(0x0FF8, mcKey.readUInt32(0x005A)); uint encryptedDataRva = peHeader.getRva(0x0FF0, mcKey.readUInt32(0x0046)); methodInfosOffset = peImage.rvaToOffset(methodInfosRva); encryptedDataOffset = peImage.rvaToOffset(encryptedDataRva); }
int getStartOffset(PeImage peImage) { int minOffset = int.MaxValue; foreach (var rva in mainType.Rvas) { int rvaOffs = (int)peImage.rvaToOffset((uint)rva); if (rvaOffs < minOffset) minOffset = rvaOffs; } return minOffset == int.MaxValue ? 0 : minOffset; }
DumpedMethods createDumpedMethods(PeImage peImage, byte[] fileData, byte[] methodsData) { var dumpedMethods = new DumpedMethods(); var methodsDataReader = new BinaryReader(new MemoryStream(methodsData)); var fileDataReader = new BinaryReader(new MemoryStream(fileData)); var metadataTables = peImage.Cor20Header.createMetadataTables(); var methodDef = metadataTables.getMetadataType(MetadataIndex.iMethodDef); uint methodDefOffset = methodDef.fileOffset; for (int i = 0; i < methodDef.rows; i++, methodDefOffset += methodDef.totalSize) { uint bodyRva = peImage.offsetReadUInt32(methodDefOffset); if (bodyRva == 0) continue; uint bodyOffset = peImage.rvaToOffset(bodyRva); var dm = new DumpedMethod(); dm.token = (uint)(0x06000001 + i); dm.mdImplFlags = peImage.offsetReadUInt16(methodDefOffset + (uint)methodDef.fields[1].offset); dm.mdFlags = peImage.offsetReadUInt16(methodDefOffset + (uint)methodDef.fields[2].offset); dm.mdName = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[3].offset, methodDef.fields[3].size); dm.mdSignature = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[4].offset, methodDef.fields[4].size); dm.mdParamList = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[5].offset, methodDef.fields[5].size); byte b = peImage.offsetReadByte(bodyOffset); uint codeOffset; if ((b & 3) == 2) { if (b != 2) continue; // not zero byte code size dm.mhFlags = 2; dm.mhMaxStack = 8; dm.mhLocalVarSigTok = 0; codeOffset = bodyOffset + 1; } else { if (peImage.offsetReadUInt32(bodyOffset + 4) != 0) continue; // not zero byte code size dm.mhFlags = peImage.offsetReadUInt16(bodyOffset); dm.mhMaxStack = peImage.offsetReadUInt16(bodyOffset + 2); dm.mhLocalVarSigTok = peImage.offsetReadUInt32(bodyOffset + 8); codeOffset = bodyOffset + (uint)(dm.mhFlags >> 12) * 4; } fileDataReader.BaseStream.Position = codeOffset; if (!decrypter.decrypt(fileDataReader, dm)) continue; dumpedMethods.add(dm); } return dumpedMethods; }