How to reverse strings that have been obfuscated using floats and double? - c

I'm working on a crackme , and having a bit of trouble making sense of the flag I'm supposed to retrieve.
I have disassembled the binary using radare2 and ghidra , ghidra gives me back the following pseudo-code:
undefined8 main(void)
{
long in_FS_OFFSET;
double dVar1;
double dVar2;
int local_38;
int local_34;
int local_30;
int iStack44;
int local_28;
undefined2 uStack36;
ushort uStack34;
char local_20;
undefined2 uStack31;
uint uStack29;
byte bStack25;
long local_10;
local_10 = *(long *)(in_FS_OFFSET + 0x28);
__printf_chk(1,"Insert flag: ");
__isoc99_scanf(&DAT_00102012,&local_38);
uStack34 = uStack34 << 8 | uStack34 >> 8;
uStack29 = uStack29 & 0xffffff00 | (uint)bStack25;
bStack25 = (undefined)uStack29;
if ((((local_38 == 0x41524146) && (local_34 == 0x7b594144)) && (local_30 == 0x62753064)) &&
(((iStack44 == 0x405f336c && (local_20 == '_')) &&
((local_28 == 0x665f646e && (CONCAT22(uStack34,uStack36) == 0x40746f31)))))) {
dVar1 = (double)CONCAT26(uStack34,CONCAT24(uStack36,0x665f646e));
dVar2 = (double)CONCAT17((undefined)uStack29,CONCAT43(uStack29,CONCAT21(uStack31,0x5f)));
__printf_chk(0x405f336c62753064,1,&DAT_00102017);
__printf_chk(dVar1,1,"y: %.30lf\n");
__printf_chk(dVar2,1,"z: %.30lf\n");
dVar1 = dVar1 * 124.8034902710365;
dVar2 = (dVar1 * dVar1) / dVar2;
round_double(dVar2,0x1e);
__printf_chk(1,"%.30lf\n");
dVar1 = (double)round_double(dVar2,0x1e);
if (1.192092895507812e-07 <= (double)((ulong)(dVar1 - 4088116.817143337) & 0x7fffffffffffffff))
{
puts("Try Again");
}
else {
puts("Well done!");
}
}
if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return 0;
}
It is easy to see that there's a part of the flag in plain-sight , but the other part is a bit more interesting :
if (1.192092895507812e-07 <= (double)((ulong)(dVar1 - 4088116.817143337) & 0x7fffffffffffffff))
From what I understand , I have to generate the missing part of the flag depending on this condition . The problem is that I absolutely have no idea how to do this .
I can assume this missing part is 8 bytes of size , according to this line :
dVar2=(double)CONCAT17((undefined)uStack29,CONCAT43(uStack29,CONCAT21(uStack31,0x5f)));`
Considering flags are usually ascii , with some special characters , let's say , each byte will have values from 0x21 to 0x7E , that's almost 8^100 combinations , which will clearly take too much time to compute.
Do you guys have an idea on how I should proceed to solve this ?
Edit : Here is the link to the binary : https://filebin.net/dpfr1nocyry3sijk

You can tweak the Ghidra reverse result by edit variable type. Based on scanf const string %32s your local_38 should be char [32].
Before the first if, there are some char swap.
And the first if statment give you a long constrain of flag
At this point, you can confirm part of flag is FARADAY{d0ubl3_#nd_f1o#t, then is ther main part of this challenge.
It print x, y, z based on the flag, but you'll quickly find x and y is constrain by the if, so you only need to solve z to get the flag, so you think you need to bruteforce all double value limit by printable ascii.
But there are a limitaion in if statment says byte0 of this double must be _ and a math constrain there, simple math tell dVar2 - 4088116.817143337 <= 1.192092895507813e-07 and it comes dVar2 is very close 4088116.817143337
And byte 3 and byte 7 in this double will swap
By reverse result: dVar2 = y*y*x*x/z, solve this equation you can say z must near 407.2786840401004 and packed to little endian is `be}uty#. Based on double internal structure format, MSB will affect exponent, so you can make sure last byte is # and it shows byte0 and byte3 is fixed now by constrain and flag common format with {} pair.
So finally, you only need to bureforce 5 bytes of printable ascii to resolve this challenge.
import string, struct
from itertools import product
possible = string.ascii_lowercase + string.punctuation + string.digits
for nxt in product(possible, repeat=5):
n = ''.join(nxt).encode()
s = b'_' + n[:2] + b'}' + n[2:] + b'#'
rtn = struct.unpack("<d", s)[0]
rtn = 1665002837.488342 / rtn
if abs(rtn - 4088116.817143337) <= 0.0000001192092895507812:
print(s)
And bingo the flag is FARADAY{d0ubl3_#nd_f1o#t_be#uty}

Related

Integer data compression for transfer in C without external libraries

I googled ans searched here a bunch without a fitting solution. The title is maybe a bit weird or not fully accurate, but let me explain:
My IoT device collects a bunch of data every second that I can represent as a list of integer. Here is an example of one row of sensor reads (the zeros are not always 0 btw):
230982 0 4294753011 -9 4294198951 -1 4294225518 0 0 0 524789 0 934585 0 4 0 0 0 0
On trigger I want to send the whole table (all rows until then) to my computer. I could just stringify it and concatenate everything, but wonder if there is a more efficient encoding/compression to reduce the byte count, both when storing in RAM/flash and for reduced transfer volume. Ideally this could be achieved with integrated functions, ie no external compression libraries. I am not that strong with encoding/compression, hope you can give me a hint.
Zlib/Zstd libraries are better suited for doing general purpose compression. If I may assume that you don't want to use any third party libraries, here is a hand coded version of some naive compression method, which saves half of the bytes of the input string.
The basic idea is very simple. Your strings will at most have 16 different characters which can be mapped to 4-bits rather than typical 8-bits. SEE THE ASSUMPTIONS BELOW. You can try base16, base64, base128 encodings too, but this is the simplest.
Assumptions:
First you'll convert all your numbers into a string in decimal format.
The string won't contain any other characters than 0,1,2,3,4,5,6,7,8,9,+,-,.,space, and a comma.
============================================================================
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static inline char map(char c)
{
switch(c) {
case ' ' : return ('/' - '*');
case '\0': return 0;
default : return c - '*';
}
return 0;
}
static inline char revmap(char c)
{
switch(c) {
case '\0' : return 0;
case '/' - '*': return ' ';
default : return c + '*';
}
return 0;
}
char *compress(const char *s, int len)
{
int i, j;
char *compr = malloc((len+1)/2 + 1);
j = 0;
for (i = 1; i < len; i += 2)
compr[j++] = map(s[i-1]) << 4 | map(s[i]);
if (i-1 < len)
compr[j++] = map(s[i-1]) << 4;
compr[j] = '\0';
return compr;
}
char *decompress(const char *s, int len)
{
int i, j;
char *decompr = malloc(2*len + 1);
for (i = j = 0; i < len; i++) {
decompr[j++] = revmap((s[i] & 0xf0) >> 4);
decompr[j++] = revmap(s[i] & 0xf);
}
decompr[j] = '\0';
return decompr;
}
int main()
{
const char *input = "230982 0 4294753011 -9 4294198951 -1 4294225518 0 0 0 524789 0 934585 0 4 0 0 0 0 ";
int plen = strlen(input);
printf("plain(len=%d): %s\n", plen, input);
char *compr = compress(input, plen);
int clen = strlen(compr);
char *decompr = decompress(compr, clen);
int dlen = strlen(decompr);
printf("decompressed(len=%d): %s\n", dlen, decompr);
free(compr);
free(decompr);
}
Simplest solution is to simply dump data out in binary form. It may be smaller or bigger than string form depending on your data, but you don't have to do any data processing on device.
If most of your data is small, you can use variable length data encoding for serialization. There are several, but CBOR is fairly simple.
If your data changes only very little, you could send only first row as absolute values, and remaining rows as delta of previous row. This would result in many small numbers, which typically are more efficient in previously mentioned encoding systems.
I wouldn't try to implement any general purpose compression algorithms without any experience and external libraries, unless you absolutely need it. Finding suitable algorithm that compresses your data well enough and with reasonable resource usage can be time consuming.

Can't extract an integer from a thermometer byte reading

Afternoon all,
Apologies if this question is in the wrong format or in the wrong place, if this is the case, please flag and I'll change it or take it elsewhere.
I am using a development board to send a temperature reading to an LCD panel and I am really struggling to comprehend as to why the temperature at the moment that the program is run isn't being printed onto my LCD. A lot of the code is from framework given to me and is correct as far as I can tell.
My question stems from these functions:
uch get_temp()
{
int i;
DQ_HIGH();
reset(); //reset,wait for 18b20 responsion
write_byte(0XCC); //ignore ROM matching
write_byte(0X44); //send temperature convert command
for(i=20;i>0;i--)
{
//display(); //call some display function,insure the time of convert temperature
}
reset(); //reset again,wait for 18b20 responsion
write_byte(0XCC); //ignore ROM matching
write_byte(0XBE); //send read temperature command
TLV=read_byte(); //read temperature low byte
THV=read_byte(); //read temperature high byte
DQ_HIGH(); //release general line
TZ=(TLV>>4)|(THV<<4)&0X3f; //temperature integer
TX=TLV<<4; //temperature decimal
if(TZ>100)
{
TZ/100;
} //not display hundred bit
ge=TZ%10; //integer Entries bit
shi=TZ/10; //integer ten bit
wd=0;
if (TX & 0x80)
wd=wd+5000;
if (TX & 0x40)
wd=wd+2500;
if (TX & 0x20)
wd=wd+1250;
if (TX & 0x10)
wd=wd+625; //hereinbefore four instructions are turn decimal into BCD code
shifen=wd/1000; //ten cent bit
baifen=(wd%1000)/100; //hundred cent bit
qianfen=(wd%100)/10; //thousand cent bit
wanfen=wd%10; //myriad cent bit
NOP();
return TZ;
}
I have modified this function so that it should return the temperature integer (unsigned char TZ)
This function is then called here:
void Init_lcd(void)
{
ADCON1 = 0x07; //required setting of analog to digital
uch Temp;
TRISD = 0x00;
TRISA1 = 0;
TRISA2 = 0;
TRISA3 = 0;
writeCommand(0x0f);
writeCommand(0x38); //set to two line mode
clearDisplay();
writeString("MAIN MENU");
Temp = get_temp();
writeString(Temp);
writeCommand(0xC0); //change cursor line
}
It isn't printing anything after "MAIN MENU", which obviously means I'm doing something wrong. I can provide further clarification/code on request.
I should probably mention that I am NOT only simply looking for an answer of "paste this in and it'll work". Any feedback in which I understand my mistake and how to fix it is greatly appreciated.
Thanks in advance!
EDIT:
A few people are asking about my writing functions so for further clarification I'll paste them here:
void writeChar(unsigned char ch)
{
lcd = ch;
RS = 1;
RW =0;
E = 1;
lcdDelay();
E=0;
}
void writeString(char *stringToLcd)
{
while(*stringToLcd > 0)
{
writeChar(*stringToLcd++);
}
}
Temp is an unsigned char
uch Temp;
//...
Temp = get_temp();
writeString(Temp);
So, using writeString() will produce undefined results.
You should use write() instead (depending on the library you're using).
But you probably want to convert the return value of get_temp() to an ASCII string first, and display that using writeString().
Update:
void writeString(char *stringToLcd)
This function needs a char*, so you can't provide a single uch.
You need to convert Temp to a string first, using itoa() for example.
I could suggest you to implement a new function
void writeUCH(uch value)
{
unsigned char test = (value >= 100) ? 100 : (value >= 10) ? 10 : 1;
while(test > 0)
{
writeChar((value/test)+'0');
value = value%test;
test /= 10;
}
}
this line:
TZ/100;
will result in no change to TZ
what you really want is this:
TZ = TZ%100;
the value returned from get_temp() is an integer, not a ascii string. I would expect the LCD needs ascii characters, not the binary value of the bytes of an int variable.

Store zeros from ints and use them later

I have 3 sensors that each provide either 0 or 1 (repeatedly in a loop). They are stored individually as int variables. These are then printed using the following:
print ("%d%d%d", Sensor1, Sensor2, Sensor3);
I want to store each combination (ex: 010, 001, 110, etc.) temporarily so that I can use it do something else (I want to have a switch or something eventually where I can do a different operation depending on the value of the sensor combination). I can't store it as an int since that drops the 0s in front.
How can I store these combinations?
You can use structure bit field for this.
struct Bit{
bool Sensor1 : 1;
bool Sensor2 : 1;
bool Sensor3 : 1;
};
int main(void)
{
struct Bit bit = {0, 1, 0};
printf ("%d%d%d", bit.Sensor1, bit.Sensor2, bit.Sensor3);
}
So you have
int Sensor1, Sensor2, Sensor3;
// have code to initialize above variables to 0 or 1
To store these as one integer in base 10, assuming they really all are 0 or 1, you can do:
int Sensors_10 = Sensor1 * 100 + Sensor2 * 10 + Sensor3;
And then to get them back:
Sensor1 = Sensors_10 / 100 % 10;
Sensor2 = Sensors_10 / 10 % 10;
Sensor3 = Sensors_10 % 10;
Obviously order of sensors can be whatever, as long as it matches between packing and unpacking.
But, you only need 1 bit to store each sensor, so could use binary:
int Sensors_2 = Sensor1 * 4 + Sensor2 * 2 + Sensor3;
...
Sensor1 = Sensors_2 / 4 % 2;
Sensor2 = Sensors_2 / 4 % 2;
Sensor3 = Sensors_2 % 2;
But, with computer binary numbers are special, so the binary version is more commonly written like this:
int Sensors_2 = Sensor1 << 2 | Sensor2 << 1 | Sensor3;
...
Sensor1 = Sensors_2 >> 2 & 1;
Sensor2 = Sensors_2 >> 1 & 1;
Sensor3 = Sensors_2 & 1;
Where |, <<, >> and & are bitwise OR, shift and AND operators, and explaining what they do is beyond scope of this question, but one note about them: When there are no "overlapping" one-bits and numbers are positive, then result of | is same as result of +.
Answer of haccks covers how to make C compiler do this for you, without doing your own bit manipulation.
To print Sensors_10 with leading zeros, you can do printf("%03d", Sensors_10);. C standard library does not have a way to print binary numbers directly, so you need your own code to print the bits one-by-one, so you might as well printf("%d%d%d", Sensor1, Sensor2, Sensor3); then.
You can use a 2D int array to store the values and use it later.
E.g int sen_value[1000][3]; use it in the loop to store the values.
Example how you can use it in loop:
#include <stdio.h>
int main ()
{
int i;
int sen_value[10][3];
for(i=0;i<10;i++)
{
//Assigning the values
sen_value[i][0] = 0;
sen_value[i][1] = 0;
sen_value[i][2] = 0;
//Use the way you want
printf("%d %d %d\n",sen_value[i][0],sen_value[i][1],sen_value[i][2]);
}
return 0;
}
Or you can use it just once and then reset it after each operation, For example:
#include <stdio.h>
int main ()
{
int sen_value[1][3];
//Assigning the values
sen_value[0][0] = 0;
sen_value[0][1] = 0;
sen_value[0][2] = 0;
//Use the way you want
printf("%d %d %d\n",sen_value[0][0],sen_value[0][1],sen_value[0][2]);
return 0;
}
If you are using a linux environment then by using the command you can easily save the output that are displayed in your console.
Let here sensor.c be your source file Then,
$ gcc -o a sensor.c
$ ./a > senser.txt
Then you have a .txt file with all output stored in a txt file. And these can be again used as inputs in your other.c files like :
$ gcc -o other other.c
$ ./other < senser.txt
If you want to store those sensor1,sensor2,sensor3 internally and use internally then you can simply use the arrays or Structure like :
main(){
int Sensor[1][3];
Sensor[0][0] = 0;
Sensor[0][1] = 1;
Sensor[0][2] = 0;
print ("%d%d%d", Sensor[0][0], Sensor[0][1], Sensor[0][2]);
}
While the leading zeroes of an integer are not displayed when printed, that does not mean they are "dropped"; they are merely implicit - that is a matter of the format specifier used in teh output of the value rather than the zeros not being present. An int is always a fixed number of binary digits.
Consider:
uint32_t sensor_state = (sensor3 << 3) | (sensor2 << 1) | sensor1 ;
Note that uint32_t is a type alias for an unsigned integer 32 bits in length. It is defined by including the <stdint.h> header file. In this case a plain int would work, but when you are dealing with data at the bit level it is good to be explicit (and unsigned). Here of course a uint8_t would work too, and if your target is an 8 bit device, I suggest you use that.
Here sensor_state is a binary combination of the three sensor values and will have one of the following values:
Sensors sensor_state
3 2 1 binary decimal hexadecimal
---------------------------------------
0 0 0 0000 0 0x00
0 0 1 0001 1 0x01
0 1 0 0010 2 0x02
0 1 1 0011 3 0x03
1 0 0 0100 4 0x04
1 0 1 0101 5 0x05
1 1 0 0110 6 0x06
1 1 1 0111 7 0x07
So you can switch on any combination:
switch( sensor_state )
{
case 0x00 :
...
break ;
case 0x01 :
...
break ;
case 0x02 :
...
break ;
...
case 0x07 :
...
break ;
default :
// unexpected invalid combination
break ;
}
You might usefully create an enumeration for each combination:
enum eSensorStates
{
NO_SENSOR = 0,
SENSOR1,
SENSOR2,
SENSOR12,
SENSOR3,
SENSOR13,
SENSOR23,
SENSOR123
}
Then you can write:
switch( sensor_state )
{
case NO_SENSOR :
...
break ;
case SENSOR1:
...
break ;
case SENSOR2:
...
break ;
...
case SENSOR123 :
...
break ;
default :
// unexpected invalid combination
break ;
}
You may of course use enumeration names that make specific sense in your application - that reflect the meaning or action for each combination rather than the generic names I have chosen.

How to optimize C for loop for font rendering on oled display

I need to optimize this function: Any strange way to optimize the for loop? (early break i think can't be possible)
void SeeedGrayOLED::putChar(unsigned char C)
{
if(C < 32 || C > 127) //Ignore non-printable ASCII characters. This can be modified for multilingual font.
{
C=' '; //Space
}
uint8_t k,offset = 0;
char bit1,bit2,c = 0;
for(char i=0;i<16;i++)
{
for(char j=0;j<32;j+=2)
{
if(i>8){
k=i-8;
offset = 1;
}else{
k=i;
}
// Character is constructed two pixel at a time using vertical mode from the default 8x8 font
c=0x00;
bit1=(pgm_read_byte(&hallfetica_normal[C-32][j+offset]) >> (8-k)) & 0x01;
bit2=(pgm_read_byte(&hallfetica_normal[C-32][j+offset]) >> ((8-k)-1)) & 0x01;
// Each bit is changed to a nibble
c|=(bit1)?grayH:0x00;
c|=(bit2)?grayL:0x00;
sendData(c);
}
}
}
I've got a font in the array hallfetica_normal, is an array of array of uint8_t, that maybe compressed or something like that?
This code run on a arduino, ad i've to run a countdown from 500 to 0 with one unit down every 10/20ms.
EDIT
This is the new code after yours indication, thanks all:
I'm looking to organise the font differently to permit less call to pgm_read_byte.. (something like changing the orientation... i wonder)
void SeeedGrayOLED::putChar(unsigned char C)
{
if(C < 32 || C > 127) //Ignore non-printable ASCII characters. This can be modified for multilingual font.
{
C=' '; //Space
}
char c,byte = 0x00;
unsigned char nibble_lookup[] = { 0, grayL, grayH, grayH | grayL };
for(int ii=0;ii<2;ii++){
for(int i=0;i<8;i++)
{
for(int j=0;j<32;j+=2)
{
byte = pgm_read_byte(&hallfetica_normal[C-32][j+ii]);
c = nibble_lookup[(byte >> (8-i)) & 3];
sendData(c);
}
}
}
}
Well, you seem to be reading the same byte twice in a row unnecessarily via pgm_read_byte(&hallfetica_normal[C-32][j+offset]). You could load that once into a local variable.
Additionally, you could avoid the if(i>8){ check per iteration by breaking up the code into two loops; one where i goes from 0 to 8 and another where it goes from 9 to 15. (Although I suspect you really intended >= here, making the loop boundaries 0-7 then 8-15.) That also means things like offset become constant values, which will help.
In an effort to make the inner loop as fast as possible, I'd try to get rid of all branching with a lookup table and see whether that helped.
First, I'd define the lookup table outside the loop:
/* outside the loop */
unsigned char h_lookup[] = { 0, grayH };
unsigned char l_lookup[] = { 0, grayL };
Then inside the loop, since you're testing the least-significant bit, you can use that as an index into the lookup table. If it's clear, then the lookup index will be 0. If it's set, then the lookup index will be 1:
/* inside the loop */
byte = pgm_read_byte(&hallfetica_normal[C-32][j+offset]);
c = h_lookup[((byte >> (8-k)) & 0x01)] |
l_lookup[((byte >> (8-k-1)) & 0x01)]
sendData(c);
Since you're masking and testing 2 adjacent bits, 8-k and 8-k-1, you could list all 4 possibilities in a single lookup table:
/* Outside loop */
unsigned char nibble_lookup[] = { 0, grayL, grayH, grayH | grayL };
And then the lookup becomes dramatically simplified.
/* loop */
byte = pgm_read_byte(&hallfetica_normal[C-32][j+offset]);
c = nibble_lookup[(byte >> (8-k)) & 3];
sendData(c);
The other answer has addressed what to do about the branches in the top part of your inner loop.

Loading ARM CPSR into C and formatting?

Whilst being given a document teaching ARM assembly the document now tells me to load the CPRS into C and format the data into a friendly format, such as -
Flags: N Z IRQ FIQ
State: ARM
Mode: Supervisor
Now I've loaded the CPRS into a variable within my program, but I'm struggling to understand what format the CPRS is in, I've seen things using hex to reset flags and etc along which bytes are control, field, status and extension masks.
I put my CPRS into an int just to see what the data shows and I'm given 1610612752, I'm assuming I shouldn't be loading it into an int and something else in order for it to be much more clear.
Any hints pushing me to the right direction would be most appreciated.
From This wiki page, (http://www.heyrick.co.uk/armwiki/The_Status_register) we get the bit layout of the CPSR (and SPSR):
31 30 29 28 27 - 24 - 19 … 16 - 9 8 7 6 5 4 … 0
N Z C V Q - J - GE[3:0] - E A I F T M[4:0]
Declare some flags (or just compute these):
int armflag_N = (Cpsr>>31)&1;
int armflag_Z = (Cpsr>>30)&1;
int armflag_C = (Cpsr>>29)&1;
int armflag_V = (Cpsr>>28)&1;
int armflag_Q = (Cpsr>>27)&1;
int armflag_J = (Cpsr>>24)&1;
int armflag_GE = (Cpsr>>16)&7;
int armflag_E = (Cpsr>>9)&1;
int armflag_A = (Cpsr>>8)&1;
int armflag_I = (Cpsr>>7)&1;
int armflag_F = (Cpsr>>6)&1;
int armflag_T = (Cpsr>>5)&1;
int armflag_M = (Cpsr>>0)&15;
(The ">>" means to rightshift specified number of bits, and "&" is the bitwise and operator, so "(val>>num)&mask" means rightshift val num bits, and then extract the bits under the mask).
Now you have variables with flags, Here is how you could conditionally print a flag,
printf("Flags: ");
printf("%s ", armflag_N ? "N" : "-" );
...

Resources