From b24dbfac80588e3da7d64b729b06a78b61b25d9e Mon Sep 17 00:00:00 2001 From: huoxue1 <3343780376@qq.com> Date: Fri, 28 Jul 2023 18:28:59 +0800 Subject: [PATCH] first commit --- .gitignore | 8 ++ CHANGELOG.md | 3 + README.md | 39 ++++++ analysis_options.yaml | 30 ++++ example/peparse_example.dart | 29 ++++ lib/peparse.dart | 11 ++ lib/src/parse.dart | 3 + lib/src/peparse_base.dart | 6 + lib/src/pojo/image_doc_header.dart | 53 +++++++ lib/src/pojo/image_nt_header.dart | 185 +++++++++++++++++++++++++ lib/src/pojo/image_section_header.dart | 49 +++++++ lib/src/pojo/reader_seeker.dart | 29 ++++ pubspec.yaml | 15 ++ test/peparse_test.dart | 0 14 files changed, 460 insertions(+) create mode 100644 .gitignore create mode 100644 CHANGELOG.md create mode 100644 README.md create mode 100644 analysis_options.yaml create mode 100644 example/peparse_example.dart create mode 100644 lib/peparse.dart create mode 100644 lib/src/parse.dart create mode 100644 lib/src/peparse_base.dart create mode 100644 lib/src/pojo/image_doc_header.dart create mode 100644 lib/src/pojo/image_nt_header.dart create mode 100644 lib/src/pojo/image_section_header.dart create mode 100644 lib/src/pojo/reader_seeker.dart create mode 100644 pubspec.yaml create mode 100644 test/peparse_test.dart diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..91964ae --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +# https://dart.dev/guides/libraries/private-files +# Created by `dart pub` +.dart_tool/ + +# Avoid committing pubspec.lock for library packages; see +# https://dart.dev/guides/libraries/private-files#pubspeclock. +pubspec.lock +.vscode/ diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..effe43c --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +## 1.0.0 + +- Initial version. diff --git a/README.md b/README.md new file mode 100644 index 0000000..8b55e73 --- /dev/null +++ b/README.md @@ -0,0 +1,39 @@ + + +TODO: Put a short description of the package here that helps potential users +know whether this package might be useful for them. + +## Features + +TODO: List what your package can do. Maybe include images, gifs, or videos. + +## Getting started + +TODO: List prerequisites and provide or point to information on how to +start using the package. + +## Usage + +TODO: Include short and useful examples for package users. Add longer examples +to `/example` folder. + +```dart +const like = 'sample'; +``` + +## Additional information + +TODO: Tell users more about the package: where to find more information, how to +contribute to the package, how to file issues, what response they can expect +from the package authors, and more. diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 0000000..95df2a7 --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1,30 @@ +# This file configures the static analysis results for your project (errors, +# warnings, and lints). +# +# This enables the 'recommended' set of lints from `package:lints`. +# This set helps identify many issues that may lead to problems when running +# or consuming Dart code, and enforces writing Dart using a single, idiomatic +# style and format. +# +# If you want a smaller set of lints you can change this to specify +# 'package:lints/core.yaml'. These are just the most critical lints +# (the recommended set includes the core lints). +# The core lints are also what is used by pub.dev for scoring packages. + + + +# Uncomment the following section to specify additional rules. + +# linter: +# rules: +# - camel_case_types + +# analyzer: +# exclude: +# - path/to/excluded/files/** + +# For more information about the core and recommended set of lints, see +# https://dart.dev/go/core-lints + +# For additional information about configuring this file, see +# https://dart.dev/guides/language/analysis-options diff --git a/example/peparse_example.dart b/example/peparse_example.dart new file mode 100644 index 0000000..199f1c5 --- /dev/null +++ b/example/peparse_example.dart @@ -0,0 +1,29 @@ + + + +import 'dart:io'; + +import '../lib/peparse.dart'; + + +void main() { + const filepath = "D:\\software\\qq\\Bin\\QQ.exe"; + File file = File(filepath); + var data = ReaderSeeker(file.readAsBytesSync()); + var header = ImageDocHeader(data); + print(header.toString()); + data.seek(header.elfanew); + var nt = ImageNtHeaders32(data); + print(nt.toString()); + print(data.position); + var sections = []; + for (var i = 0; i < nt.fileHeader.numberOfSections; i++) { + sections.add(ImageSectionHeader(data)); + } + + for (var section in sections) { + print(section.toString()); + } + + +} diff --git a/lib/peparse.dart b/lib/peparse.dart new file mode 100644 index 0000000..89502a4 --- /dev/null +++ b/lib/peparse.dart @@ -0,0 +1,11 @@ +/// Support for doing something awesome. +/// +/// More dartdocs go here. +library; + +export 'src/peparse_base.dart'; +export 'src/pojo/image_doc_header.dart' show ImageDocHeader; +export 'src/pojo/image_nt_header.dart' show ImageNtHeaders32; +export 'src/pojo/reader_seeker.dart' show ReaderSeeker; +export 'src/pojo/image_section_header.dart' show ImageSectionHeader; +// TODO: Export any libraries intended for clients of this package. diff --git a/lib/src/parse.dart b/lib/src/parse.dart new file mode 100644 index 0000000..b28b04f --- /dev/null +++ b/lib/src/parse.dart @@ -0,0 +1,3 @@ + + + diff --git a/lib/src/peparse_base.dart b/lib/src/peparse_base.dart new file mode 100644 index 0000000..e8a6f15 --- /dev/null +++ b/lib/src/peparse_base.dart @@ -0,0 +1,6 @@ +// TODO: Put public facing types in this file. + +/// Checks if you are awesome. Spoiler: you are. +class Awesome { + bool get isAwesome => true; +} diff --git a/lib/src/pojo/image_doc_header.dart b/lib/src/pojo/image_doc_header.dart new file mode 100644 index 0000000..b1be8ba --- /dev/null +++ b/lib/src/pojo/image_doc_header.dart @@ -0,0 +1,53 @@ +import 'dart:typed_data'; +import './reader_seeker.dart'; + +class ImageDocHeader { + + int emagic = 0; + int ecblp = 0; + int ecp = 0; + int ecrlc = 0; + int ecparhdr =0; + int eminalloc = 0; + int emaxalloc = 0; + int ess = 0; + int esp = 0; + int ecsum = 0; + int eip = 0; + int ecs = 0; + int elfarlc = 0; + int eovno = 0; + int eres = 0; + int eoemid = 0; + int eoeminfo = 0; + Uint8List eres2 = Uint8List(20); + int elfanew = 0; + + ImageDocHeader(ReaderSeeker reader){ + var buffer = reader.getData(64); + emagic = buffer.getUint16(0,Endian.little); + ecblp = buffer.getUint16(2,Endian.little); + ecp = buffer.getUint16(4,Endian.little); + ecrlc = buffer.getUint16(6,Endian.little); + ecparhdr = buffer.getUint16(8,Endian.little); + eminalloc = buffer.getUint16(10,Endian.little); + emaxalloc = buffer.getUint16(12,Endian.little); + ess = buffer.getUint16(14,Endian.little); + esp = buffer.getUint16(16,Endian.little); + ecsum = buffer.getUint16(18,Endian.little); + eip = buffer.getUint16(20,Endian.little); + ecs = buffer.getUint16(22,Endian.little); + elfarlc = buffer.getUint16(24,Endian.little); + eovno = buffer.getUint16(26,Endian.little); + eres = buffer.getUint64(28,Endian.little); + eoemid = buffer.getUint16(36,Endian.little); + eoeminfo = buffer.getUint16(38,Endian.little); + eres2 = buffer.buffer.asUint8List(40,20); + elfanew = buffer.getUint32(60,Endian.little); + } + + @override + String toString(){ + return '{"emagic":{${emagic.toRadixString(16)}, "ecblp":${ecblp.toRadixString(16)}, "ecp":${ecp.toRadixString(16)}, "ecrlc":${ecrlc.toRadixString(16)}, "ecparhdr":${ecparhdr.toRadixString(16)}, "eminalloc":${eminalloc.toRadixString(16)}, "emaxalloc":${emaxalloc.toRadixString(16)}, "ess":${ess.toRadixString(16)}, "esp":${esp.toRadixString(16)}, "ecsum":${ecsum.toRadixString(16)}, "eip":${eip.toRadixString(16)}, "ecs":${ecs.toRadixString(16)}, "elfarlc":${elfarlc.toRadixString(16)}, "eovno":${eovno.toRadixString(16)}, "eres":${eres.toRadixString(16)}, "eoemid":${eoemid.toRadixString(16)}, "eoeminfo":${eoeminfo.toRadixString(16)}, "eres2":${eres2.toString()}, "elfanew":${elfanew.toString()}}'; + } +} \ No newline at end of file diff --git a/lib/src/pojo/image_nt_header.dart b/lib/src/pojo/image_nt_header.dart new file mode 100644 index 0000000..e89a448 --- /dev/null +++ b/lib/src/pojo/image_nt_header.dart @@ -0,0 +1,185 @@ +import 'dart:typed_data'; +import './reader_seeker.dart'; + +class ImageNtHeaders32 { + int signature = 0; + late ImageFileHeader fileHeader; + late ImageOptionalHeader32 optionalHeader; + + ImageNtHeaders32(ReaderSeeker readerSeeker){ + var buffer = readerSeeker.getData(24); + signature = buffer.getUint32(0,Endian.little); + fileHeader = ImageFileHeader(buffer); + optionalHeader = ImageOptionalHeader32(readerSeeker); + } + + @override + String toString(){ + return '{"signature":${signature.toRadixString(16)}, "fileHeader":${fileHeader.toString()}, "optionalHeader":${optionalHeader.toString()}}'; + } +} + +class ImageFileHeader { + int machine = 0; + int numberOfSections = 0; + int timeDateStamp = 0; + int pointerToSymbolTable = 0; + int numberOfSymbols = 0; + int sizeOfOptionalHeader = 0; + int characteristics = 0; + ImageFileHeader(ByteData buffer){ + machine = buffer.getUint16(4,Endian.little); + numberOfSections = buffer.getUint16(6,Endian.little); + timeDateStamp = buffer.getUint32(8,Endian.little); + pointerToSymbolTable = buffer.getUint32(12,Endian.little); + numberOfSymbols = buffer.getUint32(16,Endian.little); + sizeOfOptionalHeader = buffer.getUint16(20,Endian.little); + characteristics = buffer.getUint16(22,Endian.little); + } + + @override + String toString(){ + return '{"machine":${machine.toRadixString(16)}, "numberOfSections":${numberOfSections.toRadixString(16)}, "timeDateStamp":${timeDateStamp.toRadixString(16)}, "pointerToSymbolTable":${pointerToSymbolTable.toRadixString(16)}, "numberOfSymbols":${numberOfSymbols.toRadixString(16)}, "sizeOfOptionalHeader":${sizeOfOptionalHeader.toRadixString(16)}, "characteristics":${characteristics.toRadixString(16)}}'; + } +} + +class ImageOptionalHeader32 { + int magic = 0; + int majorLinkerVersion = 0; + int minorLinkerVersion = 0; + int sizeOfCode = 0; + int sizeOfInitializedData = 0; + int sizeOfUninitializedData = 0; + int addressOfEntryPoint = 0; + int baseOfCode = 0; + int baseOfData = 0; + int imageBase = 0; + int sectionAlignment = 0; + int fileAlignment = 0; + int majorOperatingSystemVersion = 0; + int minorOperatingSystemVersion = 0; + int majorImageVersion = 0; + int minorImageVersion = 0; + int majorSubsystemVersion = 0; + int minorSubsystemVersion = 0; + int win32VersionValue = 0; + int sizeOfImage = 0; + int sizeOfHeaders = 0; + int checkSum = 0; + int subsystem = 0; + int dllCharacteristics = 0; + int sizeOfStackReserve = 0; + int sizeOfStackCommit = 0; + int sizeOfHeapReserve = 0; + int sizeOfHeapCommit = 0; + int loaderFlags = 0; + int numberOfRvaAndSizes = 0; + late List dataDirectory; + + bool is32 = false; + + void _parse32(ByteData buffer){ + is32 = true; + majorLinkerVersion = buffer.getUint8(0); + minorLinkerVersion = buffer.getUint8(1); + sizeOfCode = buffer.getUint32(2,Endian.little); + sizeOfInitializedData = buffer.getUint32(6,Endian.little); + sizeOfUninitializedData = buffer.getUint32(10,Endian.little); + addressOfEntryPoint = buffer.getUint32(14,Endian.little); + baseOfCode = buffer.getUint32(18,Endian.little); + baseOfData = buffer.getUint32(22,Endian.little); + + imageBase = buffer.getUint32(26,Endian.little); + sectionAlignment = buffer.getUint32(30,Endian.little); + fileAlignment = buffer.getUint32(34,Endian.little); + majorOperatingSystemVersion = buffer.getUint16(38,Endian.little); + minorOperatingSystemVersion = buffer.getUint16(40,Endian.little); + majorImageVersion = buffer.getUint16(42,Endian.little); + minorImageVersion = buffer.getUint16(44,Endian.little); + majorSubsystemVersion = buffer.getUint16(46,Endian.little); + minorSubsystemVersion = buffer.getUint16(48,Endian.little); + win32VersionValue = buffer.getUint32(50,Endian.little); + sizeOfImage = buffer.getUint32(54,Endian.little); + sizeOfHeaders = buffer.getUint32(58,Endian.little); + checkSum = buffer.getUint32(62,Endian.little); + subsystem = buffer.getUint16(66,Endian.little); + dllCharacteristics = buffer.getUint16(68,Endian.little); + sizeOfStackReserve = buffer.getUint32(70,Endian.little); + sizeOfStackCommit = buffer.getUint32(74,Endian.little); + sizeOfHeapReserve = buffer.getUint32(78,Endian.little); + sizeOfHeapCommit = buffer.getUint32(82,Endian.little); + loaderFlags = buffer.getUint32(86,Endian.little); + numberOfRvaAndSizes = buffer.getUint32(90,Endian.little); + int n = 0; + dataDirectory = List.empty(growable: true); + for (int i = 0 ;i < 16;i++){ + var data = ImageDataDirectory(); + data.virtualAddress = buffer.getUint32(94 + n,Endian.little); + data.size = buffer.getUint32(98 + n,Endian.little); + dataDirectory.add(data); + n += 8; + } + } + + void _parse64(ByteData buffer){ + is32 = false; + majorLinkerVersion = buffer.getUint8(0); + minorLinkerVersion = buffer.getUint8(1); + sizeOfCode = buffer.getUint32(2,Endian.little); + sizeOfInitializedData = buffer.getUint32(6,Endian.little); + sizeOfUninitializedData = buffer.getUint32(10,Endian.little); + addressOfEntryPoint = buffer.getUint32(14,Endian.little); + baseOfCode = buffer.getUint32(18,Endian.little); + imageBase = buffer.getUint64(22,Endian.little); + sectionAlignment = buffer.getUint32(30,Endian.little); + fileAlignment = buffer.getUint32(34,Endian.little); + majorOperatingSystemVersion = buffer.getUint16(36,Endian.little); + minorOperatingSystemVersion = buffer.getUint16(38,Endian.little); + majorImageVersion = buffer.getUint16(40,Endian.little); + minorImageVersion = buffer.getUint16(42,Endian.little); + majorSubsystemVersion = buffer.getUint16(44,Endian.little); + minorSubsystemVersion = buffer.getUint16(46,Endian.little); + win32VersionValue = buffer.getUint32(48,Endian.little); + sizeOfImage = buffer.getUint32(52,Endian.little); + sizeOfHeaders = buffer.getUint32(56,Endian.little); + checkSum = buffer.getUint32(60,Endian.little); + subsystem = buffer.getUint16(64,Endian.little); + dllCharacteristics = buffer.getUint16(66,Endian.little); + sizeOfStackReserve = buffer.getUint64(68,Endian.little); + sizeOfStackCommit = buffer.getUint64(76,Endian.little); + sizeOfHeapReserve = buffer.getUint64(84,Endian.little); + sizeOfHeapCommit = buffer.getUint64(90,Endian.little); + loaderFlags = buffer.getUint32(98,Endian.little); + numberOfRvaAndSizes = buffer.getUint32(102,Endian.little); + + int n = 0; + dataDirectory = List.empty(growable: true); + for (int i = 0 ;i < 16;i++){ + var data = ImageDataDirectory(); + data.virtualAddress = buffer.getUint32(106 + n,Endian.little); + data.size = buffer.getUint32(110 + n,Endian.little); + dataDirectory.add(data); + n += 8; + } + } + + ImageOptionalHeader32(ReaderSeeker readerSeeker){ + var buffer = readerSeeker.getData(2); + magic = buffer.getUint16(0,Endian.little); + if (magic == 267) { + _parse32(readerSeeker.getData(222)); + } else if (magic == 523) { + _parse64(readerSeeker.getData(234)); + } + } + + @override + String toString(){ + return '{"magic":"${magic},"loaderFlags":"${loaderFlags.toString()}"}'; + } +} + +class ImageDataDirectory { + int virtualAddress = 0; + int size = 0; +} \ No newline at end of file diff --git a/lib/src/pojo/image_section_header.dart b/lib/src/pojo/image_section_header.dart new file mode 100644 index 0000000..a5e01fc --- /dev/null +++ b/lib/src/pojo/image_section_header.dart @@ -0,0 +1,49 @@ +import 'dart:convert'; +import 'dart:typed_data'; + +import './reader_seeker.dart'; +class ImageSectionHeader { + + List _name = List.filled(8, 0); + + String name = ""; + + int misc = 0; + + int virtualAddress = 0; + + int sizeOfRawData = 0; + + int pointerToRawData = 0; + + int pointerToRelocations = 0; + + int pointerToLinenumbers = 0; + + int numberOfRelocations = 0; + + int numberOfLinenumbers = 0; + + int characteristics = 0; + + ImageSectionHeader(ReaderSeeker readerSeeker){ + _name = readerSeeker.getByte(8); + name = utf8.decode(_name,allowMalformed: true); + var data = readerSeeker.getData(32); + misc = data.getUint32(0,Endian.little); + virtualAddress = data.getUint32(4,Endian.little); + sizeOfRawData = data.getUint32(8,Endian.little); + pointerToRawData = data.getUint32(12,Endian.little); + pointerToRelocations = data.getUint32(16,Endian.little); + pointerToLinenumbers = data.getUint32(20,Endian.little); + numberOfRelocations = data.getUint16(24,Endian.little); + numberOfLinenumbers = data.getUint16(26,Endian.little); + characteristics = data.getUint32(28,Endian.little); + } + + @override + String toString(){ + return '{"name":"${name}", "_name": "${_name}", "misc":${misc.toRadixString(16)}, "virtualAddress":${virtualAddress.toRadixString(16)}, "sizeOfRawData":${sizeOfRawData.toRadixString(16)}, "pointerToRawData":${pointerToRawData.toRadixString(16)}, "pointerToRelocations":${pointerToRelocations.toRadixString(16)}, "pointerToLinenumbers":${pointerToLinenumbers.toRadixString(16)}, "numberOfRelocations":${numberOfRelocations.toRadixString(16)}, "numberOfLinenumbers":${numberOfLinenumbers.toRadixString(16)}, "characteristics":${characteristics.toRadixString(16)}}'; + } + +} \ No newline at end of file diff --git a/lib/src/pojo/reader_seeker.dart b/lib/src/pojo/reader_seeker.dart new file mode 100644 index 0000000..f0c1ef5 --- /dev/null +++ b/lib/src/pojo/reader_seeker.dart @@ -0,0 +1,29 @@ +import 'dart:typed_data'; + +class ReaderSeeker { + int position = 0; + int length = 0; + late Uint8List data; + ReaderSeeker(Uint8List data) { + this.data = data; + this.length = data.length; + } + + ByteData getData(int len ){ + + var buffer = ByteData.sublistView(data,position,position+len); + position += len; + return buffer; + + } + + List getByte(int len){ + var result = data.getRange(position, position+len).toList(); + position += len; + return result; + } + + void seek(int seek){ + position = seek; + } +} \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000..9ee7de3 --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,15 @@ +name: peparse +description: A starting point for Dart libraries or applications. +version: 1.0.0 +# repository: https://github.com/my_org/my_repo + +environment: + sdk: ^3.0.5 + +# Add regular dependencies here. +dependencies: + # path: ^1.8.0 + +dev_dependencies: + lints: ^2.0.0 + test: ^1.21.0 diff --git a/test/peparse_test.dart b/test/peparse_test.dart new file mode 100644 index 0000000..e69de29