Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for XOR between scan rounds #424

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 49 additions & 15 deletions handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -705,29 +705,46 @@ bool handler__lregions(globals_t * vars, char **argv, unsigned argc)
bool handler__operators(globals_t * vars, char **argv, unsigned argc)
{
uservalue_t val;
uservalue_t val2;
scan_match_type_t m;

if (argc == 1)
{
zero_uservalue(&val);
}
else if (argc > 2)
{
show_error("too many values specified, see `help %s`", argv[0]);
return false;
}
else
printf("parsing %d arguments\n", argc);

switch (argc)
{
if (!parse_uservalue_number(argv[1], &val)) {
show_error("bad value specified, see `help %s`", argv[0]);
return false;
case 3:
{
if (!parse_uservalue_number(argv[2], &val2)) {
show_error("bad 2nd value specified, see `help %s`", argv[0]);
return false;
}
/* Falls through to 2, to collect both arguments. */
}
case 2:
{
if (!parse_uservalue_number(argv[1], &val)) {
show_error("bad value specified, see `help %s`", argv[0]);
return false;
}
break;
}
case 1:
{
zero_uservalue(&val);
break;
}
default:
{
show_error("too many values specified, see `help %s`", argv[0]);
return false;
}
}


if (strcmp(argv[0], "=") == 0)
{
m = (argc == 1) ? MATCHNOTCHANGED : MATCHEQUALTO;
// TODO: warn if 3rd argument is set
}
else if (strcmp(argv[0], "!=") == 0)
{
Expand All @@ -749,6 +766,22 @@ bool handler__operators(globals_t * vars, char **argv, unsigned argc)
{
m = (argc == 1) ? MATCHDECREASED : MATCHDECREASEDBY;
}
else if (strcmp(argv[0], "^") == 0)
{
if (argc == 2) {
m = MATCHXORBY;
/* Assumes that val already contains the XOR of both clear values. */
}
else if (argc == 3) {
m = MATCHXORBY;
/* XORs val2 into val, so only &val needs to be passed into handler. */
xor_uservalue(&val, &val2);
}
else {
show_error("operator %% must have 2 arguments, but was given %d.\n", argc-1);
return false;
}
}
else
{
show_error("unrecognized operator seen at handler_operators: \"%s\".\n", argv[0]);
Expand All @@ -766,7 +799,7 @@ bool handler__operators(globals_t * vars, char **argv, unsigned argc)
}
} else {
/* Cannot be used on first scan:
* =, !=, <, >, +, + N, -, - N
* =, !=, <, >, +, + N, -, - N, % N M
* Can be used on first scan:
* = N, != N, < N, > N
*/
Expand All @@ -775,7 +808,8 @@ bool handler__operators(globals_t * vars, char **argv, unsigned argc)
m == MATCHDECREASED ||
m == MATCHINCREASED ||
m == MATCHDECREASEDBY ||
m == MATCHINCREASEDBY )
m == MATCHINCREASEDBY ||
m == MATCHXORBY )
{
show_error("cannot use that search without matches\n");
return false;
Expand Down
7 changes: 7 additions & 0 deletions handlers.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ bool handler__lregions(globals_t *vars, char **argv, unsigned argc);
#define CHANGED_SHRTDOC "match values that have changed or different from some number"
#define INCREASED_SHRTDOC "match values that have increased at all or by some number"
#define DECREASED_SHRTDOC "match values that have decreased at all or by some number"
#define XOR_SHRTDOC "match values that when xor'd equal the xor of both arguments"

#define GREATERTHAN_LONGDOC "usage: > [n]\n" \
"If n is given, match values that are greater than n.\n" \
Expand Down Expand Up @@ -194,6 +195,12 @@ bool handler__lregions(globals_t *vars, char **argv, unsigned argc);
"Otherwise match all values that have decreased. (same as `<`)\n" \
"You can use this in conjunction with `snapshot` if you never know its value."

#define XOR_LONGDOC "usage: ^ n [m]\n" \
"Takes the value of the previous round (a^x) and the current round (b^x)\n" \
"If m is given, match all values where (a^x^b^x)==(n^m)\n" \
"Otherwise match all values where (a^x^b^x)==n\n" \
"You can use this if memory has been xor'd and you know both clear values."


bool handler__operators(globals_t *vars, char **argv, unsigned argc);

Expand Down
2 changes: 2 additions & 0 deletions scanmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ bool sm_init(void)
LREGIONS_SHRTDOC, LREGIONS_LONGDOC, NULL);
sm_registercommand("version", handler__version, vars->commands,
VERSION_SHRTDOC, VERSION_LONGDOC, NULL);
sm_registercommand("^", handler__operators, vars->commands, XOR_SHRTDOC,
XOR_LONGDOC, NULL);
sm_registercommand("=", handler__operators, vars->commands, NOTCHANGED_SHRTDOC,
NOTCHANGED_LONGDOC, NULL);
sm_registercommand("!=", handler__operators, vars->commands, CHANGED_SHRTDOC,
Expand Down
43 changes: 42 additions & 1 deletion scanroutines.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,44 @@ DEFINE_INTEGER_INCREASEDBY_DECREASEDBY_ROUTINE(64)
DEFINE_FLOAT_INCREASEDBY_DECREASEDBY_ROUTINE(32)
DEFINE_FLOAT_INCREASEDBY_DECREASEDBY_ROUTINE(64)

/*-----------*/
/* for XORBY */
/*-----------*/

#define DEFINE_INTEGER_OPERATIONBY_ROUTINE_FLIP(DATAWIDTH, NAME, OP) \
extern inline unsigned int scan_routine_INTEGER##DATAWIDTH##_##NAME SCAN_ROUTINE_ARGUMENTS \
{ \
if (memlength < (DATAWIDTH)/8) return 0; \
int ret = 0; \
if ((GET_FLAG(old_value, s##DATAWIDTH##b)) && (GET_FLAG(user_value, s##DATAWIDTH##b)) && \
(get_s##DATAWIDTH##b(user_value) == (get_s##DATAWIDTH##b(memory_ptr) OP get_s##DATAWIDTH##b(old_value)))) \
{ ret = (DATAWIDTH)/8; SET_FLAG(saveflags, s##DATAWIDTH##b); } \
if ((GET_FLAG(old_value, u##DATAWIDTH##b)) && (GET_FLAG(user_value, u##DATAWIDTH##b)) && \
(get_u##DATAWIDTH##b(user_value) == (get_u##DATAWIDTH##b(memory_ptr) OP get_u##DATAWIDTH##b(old_value)))) \
{ ret = (DATAWIDTH)/8; SET_FLAG(saveflags, u##DATAWIDTH##b); } \
return ret; \
}

DEFINE_INTEGER_OPERATIONBY_ROUTINE_FLIP( 8, XORBY, ^)
DEFINE_INTEGER_OPERATIONBY_ROUTINE_FLIP(16, XORBY, ^)
DEFINE_INTEGER_OPERATIONBY_ROUTINE_FLIP(32, XORBY, ^)
DEFINE_INTEGER_OPERATIONBY_ROUTINE_FLIP(64, XORBY, ^)


#define DEFINE_FLOAT_OPERATIONBY_ROUTINE_FLIP(DATAWIDTH, FTYPE, ITYPE, NAME, OP) \
extern inline unsigned int scan_routine_FLOAT##DATAWIDTH##_##NAME SCAN_ROUTINE_ARGUMENTS \
{ \
if (memlength < (DATAWIDTH)/8) return 0; \
int ret = 0; \
if ((GET_FLAG(old_value, f##DATAWIDTH##b)) && (GET_FLAG(user_value, f##DATAWIDTH##b)) && \
(get_f##DATAWIDTH##b(user_value) == ((FTYPE)(((ITYPE)get_f##DATAWIDTH##b(memory_ptr)) OP ((ITYPE)get_f##DATAWIDTH##b(old_value)))))) \
{ ret = (DATAWIDTH)/8; SET_FLAG(saveflags, f##DATAWIDTH##b); printf("found FLOAT xor match\n"); } \
return ret; \
}

DEFINE_FLOAT_OPERATIONBY_ROUTINE_FLIP(32, float, unsigned int, XORBY, ^)
DEFINE_FLOAT_OPERATIONBY_ROUTINE_FLIP(64, double, unsigned long, XORBY, ^)

/*-----------*/
/* for RANGE */
/*-----------*/
Expand Down Expand Up @@ -337,6 +375,7 @@ DEFINE_ANYTYPE_ROUTINE(GREATERTHAN, )
DEFINE_ANYTYPE_ROUTINE(LESSTHAN, )
DEFINE_ANYTYPE_ROUTINE(INCREASEDBY, )
DEFINE_ANYTYPE_ROUTINE(DECREASEDBY, )
DEFINE_ANYTYPE_ROUTINE(XORBY, )
DEFINE_ANYTYPE_ROUTINE(RANGE, )

DEFINE_ANYTYPE_ROUTINE(EQUALTO, _REVENDIAN)
Expand Down Expand Up @@ -646,6 +685,7 @@ scan_routine_t sm_get_scanroutine(scan_data_type_t dt, scan_match_type_t mt, mat
CHOOSE_ROUTINE_FOR_ALL_NUMBER_TYPES(MATCHDECREASED, DECREASED)
CHOOSE_ROUTINE_FOR_ALL_NUMBER_TYPES(MATCHINCREASEDBY, INCREASEDBY)
CHOOSE_ROUTINE_FOR_ALL_NUMBER_TYPES(MATCHDECREASEDBY, DECREASEDBY)
CHOOSE_ROUTINE_FOR_ALL_NUMBER_TYPES(MATCHXORBY, XORBY)
CHOOSE_ROUTINE_FOR_ALL_NUMBER_TYPES_AND_ENDIANS(MATCHRANGE, RANGE)

CHOOSE_ROUTINE(BYTEARRAY, VLT, MATCHANY, ANY)
Expand Down Expand Up @@ -687,7 +727,8 @@ bool sm_choose_scanroutine(scan_data_type_t dt, scan_match_type_t mt, const user
mt == MATCHLESSTHAN ||
mt == MATCHRANGE ||
mt == MATCHINCREASEDBY ||
mt == MATCHDECREASEDBY)
mt == MATCHDECREASEDBY ||
mt == MATCHXORBY)
{
match_flags possible_flags = possible_flags_for_scan_data_type[dt];
if ((possible_flags & uflags) == flags_empty) {
Expand Down
3 changes: 2 additions & 1 deletion scanroutines.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ typedef enum {
MATCHDECREASED,
/* following: compare with both given value and old value */
MATCHINCREASEDBY,
MATCHDECREASEDBY
MATCHDECREASEDBY,
MATCHXORBY
} scan_match_type_t;


Expand Down
35 changes: 35 additions & 0 deletions test/memfake.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,41 @@ int main(int argc, char **argv)
}
}

//
printf("select xor pattern:\n");
printf("1) ...010101\n");
printf("2) ...101010\n");
printf("3) ...110011\n");
printf("4) ...100100\n");
int patnum;
scanf("%d", &patnum);
int pat;
switch (patnum) {
case 1: pat = 0b01010101010101010101010101010101; break;
case 2: pat = 0b10101010101010101010101010101010; break;
case 3: pat = 0b00110011001100110011001100110011; break;
case 4: pat = 0b00100100100100100100100100100100; break;
default: pat = -1;
}

int prev_n, cur_n;
float prev_f, f;
double prev_d, d;
while (1) {
prev_n = cur_n;
prev_f = (float)prev_n;
prev_d = (double)prev_n;
printf("enter number to xor and update memory:\n");
scanf("%d", &cur_n);

// You should search for this number.
array[17] = cur_n ^ pat;
f = (float)array[17];
d = (double)array[17];

printf("xor's value is now %d, %f, %f. Delta is %d %f %f.\n", array[17], f, d, (cur_n ^ prev_n), (float)(((unsigned int)f) ^ ((unsigned int)prev_f)), (double)(((unsigned long)d) ^ ((unsigned long)prev_d)));
}

pause();

free(array);
Expand Down
22 changes: 22 additions & 0 deletions value.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,28 @@ void uservalue2value(value_t *dst, const uservalue_t *src)
else assert(false);
}

/* Stores (src XOR dst) into dst. dst.flags must be set beforehand. */
void xor_uservalue(uservalue_t *dst, const uservalue_t *src) {

/* Zero whole value union, in case high bytes won't be set */
dst->uint64_value = 0;

/* Allows XOR on doubles and floats. */
if (dst->flags & flag_f64b) set_f64b(dst, (double)(((unsigned long)get_f64b(dst)) ^ ((unsigned long)get_f64b(src))));
if (dst->flags & flag_u64b) set_u64b(dst, get_u64b(dst) ^ get_u64b(src));
if (dst->flags & flag_s64b) set_s64b(dst, get_s64b(dst) ^ get_s64b(src));

if (dst->flags & flag_f32b) set_f32b(dst, (float)(((unsigned int)get_f32b(dst)) ^ ((unsigned int)get_f32b(src))));
if (dst->flags & flag_u32b) set_u32b(dst, get_u32b(dst) ^ get_u32b(src));
if (dst->flags & flag_s32b) set_s32b(dst, get_s32b(dst) ^ get_s32b(src));

if (dst->flags & flag_u16b) set_u16b(dst, get_u16b(dst) ^ get_u16b(src));
if (dst->flags & flag_s16b) set_s16b(dst, get_s16b(dst) ^ get_s16b(src));

if (dst->flags & flag_u8b) set_u8b (dst, get_u8b(dst) ^ get_u8b(src));
if (dst->flags & flag_s8b) set_s8b (dst, get_s8b(dst) ^ get_s8b(src));
}

/* parse bytearray, it will allocate the arrays itself, then needs to be free'd by `free_uservalue()` */
bool parse_uservalue_bytearray(char *const *argv, unsigned argc, uservalue_t *val)
{
Expand Down
1 change: 1 addition & 0 deletions value.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ bool parse_uservalue_float(const char *nptr, uservalue_t * val);
void free_uservalue(uservalue_t *uval);
void valcpy(value_t * dst, const value_t * src);
void uservalue2value(value_t * dst, const uservalue_t * src); /* dst.flags must be set beforehand */
void xor_uservalue(uservalue_t * dst, const uservalue_t * src);

#define get_s8b(val) ((val)->int8_value)
#define get_u8b(val) ((val)->uint8_value)
Expand Down