macro: fix 0E decode
binnvecs! for str arg
This commit is contained in:
parent
4c8ce5c648
commit
46526d7c27
@ -2,7 +2,6 @@ extern crate binnpatch;
|
|||||||
extern crate data_encoding;
|
extern crate data_encoding;
|
||||||
extern crate memmap;
|
extern crate memmap;
|
||||||
|
|
||||||
|
|
||||||
extern crate binnpatch_macro;
|
extern crate binnpatch_macro;
|
||||||
|
|
||||||
use data_encoding::HEXUPPER;
|
use data_encoding::HEXUPPER;
|
||||||
@ -11,15 +10,15 @@ use std::fs;
|
|||||||
use std::fs::{File, OpenOptions};
|
use std::fs::{File, OpenOptions};
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
use binnpatch::{BytesPattern, FindPattern, ApplyPatch};
|
use binnpatch::{ApplyPatch, BytesPattern, FindPattern};
|
||||||
use binnpatch_macro::binnvec;
|
use binnpatch_macro::binnvecs;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let src_file = "Some.dll";
|
let src_file = "Some.dll";
|
||||||
let dst_file = "Some.dll.patched";
|
let dst_file = "Some.dll.patched";
|
||||||
let src_pattern =
|
let src_pattern = "40 3E 1D ?? ?? 12 1C 7C 48 ?? 73 6F 02 22 ?? 61 19 4E 13 60 48 45 19 27 5B";
|
||||||
"40 3E 1D ?? ?? 12 1C 7C 48 ?? 73 6F 02 22 ?? 61 19 4E 13 60 48 45 19 27 5B";
|
let replacement =
|
||||||
let replacement = binnvec!(06 5A 18 74 2D 62 12 6A 13 4A 2B 0E 6F 0F 36 7A 28 0A 37 67 0A 4B 01 73 0x14);
|
binnvecs!("06 5A 18 74 2D 62 12 6A 13 4A 2B 0E 6F 0F 36 7A 28 0A 37 67 0A 4B 01 73 14");
|
||||||
|
|
||||||
let pattern = BytesPattern::from(src_pattern);
|
let pattern = BytesPattern::from(src_pattern);
|
||||||
|
|
||||||
|
203
macro/src/lib.rs
203
macro/src/lib.rs
@ -1,91 +1,112 @@
|
|||||||
extern crate proc_macro;
|
extern crate proc_macro;
|
||||||
use proc_macro::{TokenStream, TokenTree};
|
use proc_macro::{TokenStream, TokenTree};
|
||||||
|
|
||||||
use proc_macro::{Punct, Literal, Spacing, Span, Ident, Group, Delimiter};
|
use proc_macro::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span};
|
||||||
|
|
||||||
fn parse_str(s: &str) -> TokenStream {
|
macro_rules! forest {
|
||||||
s.parse().unwrap()
|
($($x:expr),+) => {[$( TokenTree::from($x), )+]};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[proc_macro]
|
fn parse_hex_values(items: TokenStream) -> TokenStream {
|
||||||
pub fn binnvec(_item: TokenStream) -> TokenStream {
|
let mut new_tokens: Vec<TokenTree> = vec![];
|
||||||
println!("- - - - -");
|
let comma: Punct = Punct::new(',', Spacing::Alone);
|
||||||
println!("{}", _item.to_string());
|
let zero = Literal::u8_suffixed(0);
|
||||||
println!("- - - - -");
|
let mut prev_separated: bool = true;
|
||||||
println!("{:?}", _item);
|
let mut prev_is_mask: bool = false;
|
||||||
println!("- - - - -");
|
|
||||||
|
for token in items {
|
||||||
let mut new_tokens: Vec<TokenTree> = vec![];
|
match token {
|
||||||
let comma: Punct = Punct::new(',', Spacing::Alone);
|
TokenTree::Punct(ref x) if x.as_char() == ',' => {
|
||||||
let zero = Literal::u8_suffixed(0);
|
new_tokens.push(token);
|
||||||
let mut prev_separated: bool = true;
|
prev_separated = true;
|
||||||
let mut prev_is_mask: bool = false;
|
continue;
|
||||||
|
}
|
||||||
for token in _item {
|
TokenTree::Punct(ref x) if x.as_char() == '?' => {
|
||||||
match token {
|
if prev_is_mask {
|
||||||
TokenTree::Punct(ref x) if x.as_char() == ',' => {
|
if !prev_separated {
|
||||||
new_tokens.push(token.into());
|
new_tokens.push(comma.clone().into());
|
||||||
prev_separated = true;
|
}
|
||||||
continue;
|
let mut val = zero.clone();
|
||||||
}
|
val.set_span(x.span());
|
||||||
TokenTree::Punct(ref x) if x.as_char() == '?' => {
|
new_tokens.push(zero.clone().into());
|
||||||
if prev_is_mask {
|
prev_is_mask = false;
|
||||||
if !prev_separated {
|
prev_separated = false;
|
||||||
new_tokens.push(comma.clone().into());
|
} else if !prev_is_mask {
|
||||||
}
|
prev_is_mask = true;
|
||||||
let mut val = zero.clone();
|
}
|
||||||
val.set_span(x.span());
|
continue;
|
||||||
new_tokens.push(zero.clone().into());
|
}
|
||||||
prev_is_mask = false;
|
TokenTree::Ident(ref x) if x.to_string().len() == 2 => {
|
||||||
prev_separated = false;
|
if !prev_separated {
|
||||||
} else if !prev_is_mask {
|
new_tokens.push(comma.clone().into());
|
||||||
prev_is_mask = true;
|
}
|
||||||
}
|
let lit_str = format!("0x{}u8", x);
|
||||||
continue;
|
let mut val: Literal = lit_str.as_str().parse().expect("parse literal from ident");
|
||||||
}
|
val.set_span(x.span());
|
||||||
TokenTree::Ident(ref x) if x.to_string().len() == 2 => {
|
new_tokens.push(val.into());
|
||||||
if !prev_separated {
|
}
|
||||||
new_tokens.push(comma.clone().into());
|
TokenTree::Literal(ref x) => {
|
||||||
}
|
if !prev_separated {
|
||||||
let lit_str = format!("0x{}u8", x.to_string());
|
new_tokens.push(comma.clone().into());
|
||||||
let mut val:Literal = lit_str.as_str().parse().expect("parse literal from ident");
|
}
|
||||||
val.set_span(x.span());
|
|
||||||
new_tokens.push(val.into());
|
let in_str = x.to_string();
|
||||||
}
|
if in_str.starts_with("0x") {
|
||||||
TokenTree::Literal(ref x) => {
|
new_tokens.push(token);
|
||||||
if !prev_separated {
|
} else {
|
||||||
new_tokens.push(comma.clone().into());
|
let lit_str = format!("0x{}u8", in_str);
|
||||||
}
|
let mut val: Literal = lit_str.as_str().parse().expect("parse literal");
|
||||||
|
val.set_span(x.span());
|
||||||
let in_str = x.to_string();
|
new_tokens.push(val.into());
|
||||||
if in_str.starts_with("0x") {
|
}
|
||||||
new_tokens.push(token.into());
|
}
|
||||||
} else {
|
_ => {}
|
||||||
let lit_str = format!("0x{}u8", in_str);
|
}
|
||||||
let mut val:Literal = lit_str.as_str().parse().expect("parse literal");
|
prev_separated = false;
|
||||||
val.set_span(x.span());
|
}
|
||||||
new_tokens.push(val.into());
|
let mut new_stream = TokenStream::new();
|
||||||
}
|
new_stream.extend(new_tokens);
|
||||||
}
|
new_stream
|
||||||
_ => {
|
}
|
||||||
|
|
||||||
}
|
#[proc_macro]
|
||||||
}
|
pub fn binnvec(_item: TokenStream) -> TokenStream {
|
||||||
prev_separated = false;
|
let group_elements = parse_hex_values(_item);
|
||||||
}
|
|
||||||
|
let group = Group::new(Delimiter::Bracket, group_elements);
|
||||||
let mut ts_new = TokenStream::new();
|
let mut result = TokenStream::new();
|
||||||
ts_new.extend(new_tokens);
|
let vec_ident = Ident::new("vec", Span::call_site());
|
||||||
|
let macro_marc = Punct::new('!', Spacing::Joint);
|
||||||
let group = Group::new(Delimiter::Bracket, ts_new);
|
result.extend(forest!(vec_ident, macro_marc, group));
|
||||||
let mut result = TokenStream::new();
|
|
||||||
let vec_ident = Ident::new("vec", Span::call_site());
|
result
|
||||||
let macro_marc = Punct::new('!', Spacing::Joint);
|
}
|
||||||
result.extend([TokenTree::from(vec_ident), TokenTree::from(macro_marc)]);
|
|
||||||
result.extend([TokenTree::from(group)]);
|
#[proc_macro]
|
||||||
|
pub fn binnvecs(_item: TokenStream) -> TokenStream {
|
||||||
println!("result: \"{}\"", result.to_string());
|
let first = _item.clone().into_iter().next();
|
||||||
|
|
||||||
result
|
match first {
|
||||||
}
|
Some(TokenTree::Literal(lit)) => {
|
||||||
|
let mut lit_str = lit.to_string();
|
||||||
|
if !(lit_str.starts_with('\"') && lit_str.ends_with('\"')) {
|
||||||
|
panic!("unexpected literal: \"{}\"", lit_str);
|
||||||
|
}
|
||||||
|
lit_str = lit_str.trim_matches('"').to_string();
|
||||||
|
let lit_str_copy = lit_str.clone();
|
||||||
|
|
||||||
|
(0u8..=9)
|
||||||
|
.map(|i| i.to_string())
|
||||||
|
.filter(|x| lit_str_copy.contains(format!("{}E", x).as_str()))
|
||||||
|
.for_each(|x| {
|
||||||
|
lit_str =
|
||||||
|
lit_str.replace(format!("{}E", x).as_str(), format!("0x{}E", x).as_str());
|
||||||
|
});
|
||||||
|
let stream: TokenStream = lit_str.parse().unwrap();
|
||||||
|
binnvec(stream)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
panic!("invalid item: \"{}\"", _item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user