How to get the value of a variable in dwarf? - c

I am parsing dwarf files, and I want to get the value of a variable or a pointer.
For example,
#include<stdio.h>
int main(){
int *a=malloc(4*sizeof(int));
a[0]=1;
int *b=&a;
int c=a[0];
return 0;
}
I got the dwarf debug information like this:
<2><304>: Abbrev Number: 17 (DW_TAG_variable)
<305> DW_AT_name : a
<307> DW_AT_decl_file : 1
<308> DW_AT_decl_line : 4
<309> DW_AT_decl_column : 10
<30a> DW_AT_type : <0x341>
<30e> DW_AT_location : 2 byte block: 91 58 (DW_OP_fbreg: -40)
<2><311>: Abbrev Number: 18 (DW_TAG_subprogram)
<312> DW_AT_external : 1
<312> DW_AT_name : (indirect string, offset: 0x3f): malloc
<316> DW_AT_decl_file : 8
<317> DW_AT_decl_line : 0
<318> DW_AT_prototyped : 1
<318> DW_AT_type : <0x47>
<31c> DW_AT_declaration : 1
<31c> DW_AT_sibling : <0x326>
<3><320>: Abbrev Number: 19 (DW_TAG_formal_parameter)
<321> DW_AT_type : <0x39>
<3><325>: Abbrev Number: 0
<2><326>: Abbrev Number: 17 (DW_TAG_variable)
<327> DW_AT_name : b
<329> DW_AT_decl_file : 1
<32a> DW_AT_decl_line : 7
<32b> DW_AT_decl_column : 10
<32c> DW_AT_type : <0x341>
<330> DW_AT_location : 2 byte block: 91 60 (DW_OP_fbreg: -32) [without DW_AT_frame_base]
<2><333>: Abbrev Number: 17 (DW_TAG_variable)
<334> DW_AT_name : c
<336> DW_AT_decl_file : 1
<337> DW_AT_decl_line : 8
<338> DW_AT_decl_column : 9
<339> DW_AT_type : <0x65>
<33d> DW_AT_location : 2 byte block: 91 54 (DW_OP_fbreg: -44) [without DW_AT_frame_base]
I get the name,type,frame base offset of a,b and c, but could I know the value of int *b and int c ?

Related

gdb doesn't find debug info for local static variables

I'm having trouble accessing debug information for local static variables with gdb. I created a very simple example that shows the behaviour:
int global = 0;
static int g_static = 1;
int main(void)
{
static int l_static = 2;
return global + g_static + l_static;
}
I compiled with arm-none-eabi-gcc (I'm compiling for an MCU target) using -O0 and -gdwarf-2 and I can see the debug information for all 3 variables in the output of objdump -g:
<1><29>: Abbrev Number: 2 (DW_TAG_variable)
<2a> DW_AT_name : (indirect string, offset: 0x9): global
<2e> DW_AT_decl_file : 1
<2f> DW_AT_decl_line : 1
<30> DW_AT_decl_column : 5
<31> DW_AT_type : <0x3c>
<35> DW_AT_external : 1
<36> DW_AT_location : 5 byte block: 3 0 0 0 0 (DW_OP_addr: 0)
<1><3c>: Abbrev Number: 3 (DW_TAG_base_type)
<3d> DW_AT_byte_size : 4
<3e> DW_AT_encoding : 5 (signed)
<3f> DW_AT_name : int
<1><43>: Abbrev Number: 4 (DW_TAG_variable)
<44> DW_AT_name : (indirect string, offset: 0xac): g_static
<48> DW_AT_decl_file : 1
<49> DW_AT_decl_line : 2
<4a> DW_AT_decl_column : 12
<4b> DW_AT_type : <0x3c>
<4f> DW_AT_location : 5 byte block: 3 0 0 0 0 (DW_OP_addr: 0)
<1><55>: Abbrev Number: 5 (DW_TAG_subprogram)
<56> DW_AT_external : 1
<57> DW_AT_name : (indirect string, offset: 0x17): main
<5b> DW_AT_decl_file : 1
<5c> DW_AT_decl_line : 4
<5d> DW_AT_decl_column : 5
<5e> DW_AT_prototyped : 1
<5f> DW_AT_type : <0x3c>
<63> DW_AT_low_pc : 0x0
<67> DW_AT_high_pc : 0x28
<6b> DW_AT_frame_base : 0x0 (location list)
<6f> DW_AT_GNU_all_call_sites: 1
<2><70>: Abbrev Number: 4 (DW_TAG_variable)
<71> DW_AT_name : (indirect string, offset: 0x0): l_static
<75> DW_AT_decl_file : 1
<76> DW_AT_decl_line : 6
<77> DW_AT_decl_column : 14
<78> DW_AT_type : <0x3c>
<7c> DW_AT_location : 5 byte block: 3 0 0 0 0 (DW_OP_addr: 0)
In the symbol table l_static is given a suffix to make it unique and prevent ambiguity. nm output:
00000000 b $d
00000000 d $d
00000000 d $d
0000001c t $d
00000000 t $t
00000000 d g_static
00000000 B global
00000000 d l_static.0
00000001 T main
Yet when I try to access it using gdb, I can only access debug info for global and g_static but not for l_static or even 'l_static.0'. It looks like gdb knows about the existence of l_static.0but can't find the related debug info.:
(gdb) ptype global
type = int
(gdb) ptype g_static
type = int
(gdb) ptype l_static
No symbol "l_static" in current context.
(gdb) ptype 'l_static.0'
type = <data variable, no debug info>
I have tried with gdb 7.6.1 and 11.2 with the same result. As far as I understand it the information is there, as shown by the output of objdump -g. But for some reason gdb can't find it.
My gut feeling is that this might be related to the way gcc appends the .0 to the local static's symbol name. Maybe this leads to a mismatch between the symbol name and the name related to the debug info?
Hoping for anyone who can shed some light on this. Thanks in advance!
You need to stop inside the main function to see that variable:
I found out how to do it without running the binary and setting a breakpoint.
(gdb) ptype main::l_static
type = int
Apparently gdb knows in which function the local static is defined and lets you access it in this c++ namespace-style way, even if the relevant stack frame has not been selected. This is documented in section 10.3 of the gdb manual.

How does debugger know the local variables' name?

I begin to learn compiler.
I know that .symtab in ELF stores information about global variables and functions, but I don't find any valid information about local variables. For those local variables that are allocated on the stack, how could a debugger know their name? Are there any helpful information in ELF?
For example, here is a stupid C code:
void printLocal(){
char c1_loc='a';
int i_loc=1;
char c2_loc='b';
double d_loc=2;
char c3_loc='c';
float f_loc=3;
char c4_loc='d';
short s_loc=4;
printf("&c1_loc = %p\n",&c1_loc);
printf("&i_loc = %p\n",&i_loc);
printf("&c2_loc = %p\n",&c2_loc);
printf("&d_loc = %p\n",&d_loc);
printf("&c3_loc = %p\n",&c3_loc);
printf("&f_loc = %p\n",&f_loc);
printf("&c4_loc = %p\n",&c4_loc);
printf("&s_loc = %p\n",&s_loc);
}
And I get the .debug_info in ELF :
<1><490>: Abbrev Number: 19 (DW_TAG_subprogram)
<491> DW_AT_external : 1
<491> DW_AT_name : (indirect string, offset: 0x2b): printLocal
<495> DW_AT_decl_file : 1
<496> DW_AT_decl_line : 42
<497> DW_AT_decl_column : 6
<498> DW_AT_low_pc : 0x12ff
<4a0> DW_AT_high_pc : 0x129
<4a8> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa)
<4aa> DW_AT_GNU_all_tail_call_sites: 1
<4aa> DW_AT_sibling : <0x527>
<2><4ae>: Abbrev Number: 20 (DW_TAG_variable)
<4af> DW_AT_name : (indirect string, offset: 0x13d): c1_loc
<4b3> DW_AT_decl_file : 1
<4b4> DW_AT_decl_line : 43
<4b5> DW_AT_decl_column : 10
<4b6> DW_AT_type : <0x91>
<4ba> DW_AT_location : 2 byte block: 91 52 (DW_OP_fbreg: -46)
<2><4bd>: Abbrev Number: 20 (DW_TAG_variable)
<4be> DW_AT_name : (indirect string, offset: 0xc): i_loc
<4c2> DW_AT_decl_file : 1
<4c3> DW_AT_decl_line : 44
<4c4> DW_AT_decl_column : 9
<4c5> DW_AT_type : <0x65>
<4c9> DW_AT_location : 2 byte block: 91 58 (DW_OP_fbreg: -40)
<2><4cc>: Abbrev Number: 20 (DW_TAG_variable)
<4cd> DW_AT_name : (indirect string, offset: 0x126): c2_loc
<4d1> DW_AT_decl_file : 1
<4d2> DW_AT_decl_line : 45
<4d3> DW_AT_decl_column : 10
<4d4> DW_AT_type : <0x91>
<4d8> DW_AT_location : 2 byte block: 91 53 (DW_OP_fbreg: -45)
<2><4db>: Abbrev Number: 20 (DW_TAG_variable)
<4dc> DW_AT_name : (indirect string, offset: 0xce): d_loc
<4e0> DW_AT_decl_file : 1
<4e1> DW_AT_decl_line : 46
<4e2> DW_AT_decl_column : 12
<4e3> DW_AT_type : <0x334>
<4e7> DW_AT_location : 2 byte block: 91 60 (DW_OP_fbreg: -32)
<2><4ea>: Abbrev Number: 20 (DW_TAG_variable)
<4eb> DW_AT_name : (indirect string, offset: 0x333): c3_loc
<4ef> DW_AT_decl_file : 1
<4f0> DW_AT_decl_line : 47
<4f1> DW_AT_decl_column : 10
<4f2> DW_AT_type : <0x91>
<4f6> DW_AT_location : 2 byte block: 91 54 (DW_OP_fbreg: -44)
<2><4f9>: Abbrev Number: 20 (DW_TAG_variable)
<4fa> DW_AT_name : (indirect string, offset: 0x32d): f_loc
<4fe> DW_AT_decl_file : 1
<4ff> DW_AT_decl_line : 48
<500> DW_AT_decl_column : 11
<501> DW_AT_type : <0x364>
<505> DW_AT_location : 2 byte block: 91 5c (DW_OP_fbreg: -36)
<2><508>: Abbrev Number: 20 (DW_TAG_variable)
<509> DW_AT_name : (indirect string, offset: 0x159): c4_loc
<50d> DW_AT_decl_file : 1
<50e> DW_AT_decl_line : 49
<50f> DW_AT_decl_column : 10
<510> DW_AT_type : <0x91>
<514> DW_AT_location : 2 byte block: 91 55 (DW_OP_fbreg: -43)
<2><517>: Abbrev Number: 20 (DW_TAG_variable)
<518> DW_AT_name : (indirect string, offset: 0x1e): s_loc
<51c> DW_AT_decl_file : 1
<51d> DW_AT_decl_line : 50
<51e> DW_AT_decl_column : 11
<51f> DW_AT_type : <0x5e>
<523> DW_AT_location : 2 byte block: 91 56 (DW_OP_fbreg: -42)
when I use GDB to debug the program, I get:
(gdb) info locals
c1_loc = 97 'a'
i_loc = 1
c2_loc = 98 'b'
d_loc = 2
c3_loc = 99 'c'
f_loc = 3
c4_loc = 100 'd'
s_loc = 4
I don't know how GDB get the name of the local variables, hope someone could help me.

Input integers from CSV file( graph adjacency list) in C

I'm trying to implement the BFS algorithm to determine the shortest path between two nodes.For that I have been given the graph as an input csv file which is the adjacency list.I plan to store this list as an array of struct "rel" and get input from the file shown in the code.However, the output doesn't show the correct values.
#include<stdlib.h>
#include<stdio.h>
typedef struct relation // to store the pair of integers in a csv file line (c connected to y
{
int x;
int y;
}rel; // relation
void split(char* buffer,char* string1,char* string2) // spilts buffer into two strings seperated by ,
{
char* buffer_trav = buffer; // trav ptr in buffer
char* string_trav = string1; // trav ptr to string 1 or 2(after ',' is read)
while(*buffer_trav!='\0')
{
if(*buffer_trav==',')
{
string_trav = string2;
buffer_trav+=1;
}
else
{
*string_trav = *buffer_trav;
string_trav+=1;
buffer_trav+=1;
}
}
}
int main(void)
{
FILE* fp = fopen("graph.csv","r"); // reading csv file
int max_number_data = 100; // maximum number of edge relations in the file
rel graph[max_number_data];
for(int i=0;i<max_number_data;i++)
{
graph[i].x=1 ;
graph[i].y=-1 ; // setting initial value to be used as a check point for other functions
}
char buffer[10];//buffer for input
char x_buffer[5];// buffer for name
char y_buffer[5]; // buffer for password
int count=0;
while(fgets(buffer,10,fp)!=NULL)
{
char* ptr; // to be used to convert string to integer;
split(buffer,x_buffer,y_buffer); // splits into two strings
printf("%s : %s;\n",x_buffer,y_buffer); // To debug
graph[count].x = (int)strtol(x_buffer,&ptr,10); // converts string to longint which is later cat into int
graph[count].y = (int)strtol(y_buffer,&ptr,10); // " " " " " " " " " " " " "" " " " " "" " "" "" " " ""
count++;
}
fclose(fp);
}
Input file:
0,1
0,2
0,3
0,4
0,5
0,6
0,7
0,8
0,10
0,11
0,12
0,13
0,17
0,19
0,21
0,31
1,0
1,2
1,3
1,7
1,13
1,17
1,19
1,21
1,30
2,0
2,1
2,3
2,7
2,8
2,9
2,13
2,27
2,28
2,32
3,0
3,1
3,2
3,7
3,12
3,13
4,0
4,6
4,10
5,0
5,6
5,10
5,16
6,0
6,4
6,5
6,16
7,0
7,1
7,2
7,3
8,0
8,2
8,30
8,32
8,33
9,2
9,33
10,0
10,4
10,5
11,0
12,0
12,3
13,0
13,1
13,2
13,3
13,33
14,32
14,33
15,32
15,33
16,5
16,6
17,0
17,1
18,32
18,33
19,0
19,1
19,33
20,32
20,33
21,0
21,1
22,32
22,33
23,25
23,27
23,29
23,32
23,33
24,25
24,27
24,31
25,23
25,24
25,31
26,29
26,33
27,2
27,23
27,24
27,33
28,2
28,31
28,33
29,23
29,26
29,32
29,33
30,1
30,8
30,32
30,33
31,0
31,24
31,25
31,28
31,32
31,33
32,2
32,8
32,14
32,15
32,18
32,20
32,22
32,23
32,29
32,30
32,31
32,33
33,8
33,9
33,13
33,14
33,15
33,18
33,19
33,20
33,22
33,23
33,26
33,27
33,28
33,29
33,30
33,31
33,32
The output( Debugging ) I get is:
0`#?d : 1
;
0`#?d : 2
;
0`#?d : 3
;
0`#?d : 4
;
0`#?d : 5
;
0`#?d : 6
;
0`#?d : 7
;
0`#?d : 8
;
0`#?d : 10
;
0`#?d : 11
;
0`#?d : 12
;
0`#?d : 13
;
0`#?d : 17
;
0`#?d : 19
;
0`#?d : 21
;
0`#?d : 31
;
1`#?d : 0
;
1`#?d : 2
;
1`#?d : 3
;
1`#?d : 7
;
1`#?d : 13
;
1`#?d : 17
;
1`#?d : 19
;
1`#?d : 21
;
1`#?d : 30
;
2`#?d : 0
;
2`#?d : 1
;
2`#?d : 3
;
2`#?d : 7
;
2`#?d : 8
;
2`#?d : 9
;
2`#?d : 13
;
2`#?d : 27
;
2`#?d : 28
;
2`#?d : 32
;
3`#?d : 0
;
3`#?d : 1
;
3`#?d : 2
;
3`#?d : 7
;
3`#?d : 12
;
3`#?d : 13
;
4`#?d : 0
;
4`#?d : 6
;
4`#?d : 10
;
5`#?d : 0
;
5`#?d : 6
;
5`#?d : 10
;
5`#?d : 16
;
6`#?d : 0
;
6`#?d : 4
;
6`#?d : 5
;
6`#?d : 16
;
7`#?d : 0
;
7`#?d : 1
;
7`#?d : 2
;
7`#?d : 3
;
8`#?d : 0
;
8`#?d : 2
;
8`#?d : 30
;
8`#?d : 32
;
8`#?d : 33
;
9`#?d : 2
;
9`#?d : 33
;
10#?d : 0
;
10#?d : 4
;
10#?d : 5
;
11#?d : 0
;
12#?d : 0
;
12#?d : 3
;
13#?d : 0
;
13#?d : 1
;
13#?d : 2
;
13#?d : 3
;
13#?d : 33
;
14#?d : 32
;
14#?d : 33
;
15#?d : 32
;
15#?d : 33
;
16#?d : 5
;
16#?d : 6
;
17#?d : 0
;
17#?d : 1
;
18#?d : 32
;
18#?d : 33
;
19#?d : 0
;
19#?d : 1
;
19#?d : 33
;
20#?d : 32
;
20#?d : 33
;
21#?d : 0
;
21#?d : 1
;
22#?d : 32
;
22#?d : 33
;
23#?d : 25
;
23#?d : 27
;
23#?d : 29
;
23#?d : 32
;
23#?d : 33
;
24#?d : 25
;
24#?d : 27
;
24#?d : 31
;
25#?d : 23
;
25#?d : 24
;
zsh: segmentation fault ./a.out
The issue was that strings were not terminated with null characters.Also, the segmentation fault occurred because while the csv file had around 200 lines, I initiated maximum input lines to 100.

Reading multitouch using libevdev

I'm trying to read raw multitouch data from my touchpad, though I'm not getting the results I expect.
I started by identifying what my device ID was, using lsinput:
/dev/input/event0
bustype : BUS_HOST
vendor : 0x0
product : 0x5
version : 0
name : "Lid Switch"
phys : "PNP0C0D/button/input0"
bits ev : EV_SYN EV_SW
/dev/input/event1
bustype : BUS_HOST
vendor : 0x0
product : 0x1
version : 0
name : "Power Button"
phys : "PNP0C0C/button/input0"
bits ev : EV_SYN EV_KEY
/dev/input/event2
bustype : BUS_HOST
vendor : 0x0
product : 0x1
version : 0
name : "Power Button"
phys : "LNXPWRBN/button/input0"
bits ev : EV_SYN EV_KEY
/dev/input/event3
bustype : BUS_I8042
vendor : 0x1
product : 0x1
version : 43907
name : "AT Translated Set 2 keyboard"
phys : "isa0060/serio0/input0"
bits ev : EV_SYN EV_KEY EV_MSC EV_LED EV_REP
/dev/input/event4
bustype : BUS_HOST
vendor : 0x0
product : 0x6
version : 0
name : "Video Bus"
phys : "LNXVIDEO/video/input0"
bits ev : EV_SYN EV_KEY
/dev/input/event5
bustype : BUS_HOST
vendor : 0x0
product : 0x6
version : 0
name : "Video Bus"
phys : "LNXVIDEO/video/input0"
bits ev : EV_SYN EV_KEY
/dev/input/event6
bustype : BUS_I8042
vendor : 0x2
product : 0x7
version : 433
name : "SynPS/2 Synaptics TouchPad"
phys : "isa0060/serio1/input0"
bits ev : EV_SYN EV_KEY EV_ABS
/dev/input/event7
bustype : BUS_HOST
vendor : 0x0
product : 0x0
version : 0
name : "Ideapad extra buttons"
phys : "ideapad/input0"
bits ev : EV_SYN EV_KEY EV_MSC
/dev/input/event8
bustype : BUS_USB
vendor : 0x4f2
product : 0xb57e
version : 34624
name : "EasyCamera: EasyCamera"
phys : "usb-0000:00:14.0-6/button"
bits ev : EV_SYN EV_KEY
/dev/input/event9
bustype : (null)
vendor : 0x0
product : 0x0
version : 0
name : "HDA Intel PCH Mic"
phys : "ALSA"
bits ev : EV_SYN EV_SW
/dev/input/event10
bustype : (null)
vendor : 0x0
product : 0x0
version : 0
name : "HDA Intel PCH Headphone"
phys : "ALSA"
bits ev : EV_SYN EV_SW
/dev/input/event11
bustype : (null)
vendor : 0x0
product : 0x0
version : 0
name : "HDA Intel PCH HDMI/DP,pcm=3"
phys : "ALSA"
bits ev : EV_SYN EV_SW
/dev/input/event12
bustype : (null)
vendor : 0x0
product : 0x0
version : 0
name : "HDA Intel PCH HDMI/DP,pcm=7"
phys : "ALSA"
bits ev : EV_SYN EV_SW
/dev/input/event13
bustype : (null)
vendor : 0x0
product : 0x0
version : 0
name : "HDA Intel PCH HDMI/DP,pcm=8"
phys : "ALSA"
bits ev : EV_SYN EV_SW
/dev/input/event14
bustype : (null)
vendor : 0x0
product : 0x0
version : 0
name : "HDA Intel PCH HDMI/DP,pcm=9"
phys : "ALSA"
bits ev : EV_SYN EV_SW
/dev/input/event15
bustype : (null)
vendor : 0x0
product : 0x0
version : 0
name : "HDA Intel PCH HDMI/DP,pcm=10"
phys : "ALSA"
bits ev : EV_SYN EV_SW
Since I could see none of the devices listed here, I decided to choose /dev/input/event6 (SynPS/2 Synaptics TouchPad) which seemed the closest to what I was looking for.
Now, I've written a dead-simple code to try and get the max number of MT points from it:
int main(void)
{
struct libevdev *dev;
int fd;
int rc;
fd = open("/dev/input/event6", O_RDONLY|O_NONBLOCK);
if (fd < 0)
fprintf(stderr, "error: %d %s\n", errno, strerror(errno));
rc = libevdev_new_from_fd(fd, &dev);
if (rc < 0)
fprintf(stderr, "error: %d %s\n", -rc, strerror(-rc));
int n = libevdev_get_num_slots(dev);
printf("%d\n", n);
return 0;
}
I can compile it using gcc -levdev myfile.c and run it properly, but I only get 2.
Does that mean that my touchpad only handles two points ? This is weird, since it can handle (at least) 4 on Windows.
Do you have any ideas about this?
Small update : using libinput-debug-events, I get the following output
When using 1 finger:
event6 POINTER_MOTION +0.79s 0.00/ -6.22
event6 POINTER_MOTION +0.80s 0.00/-11.26
event6 POINTER_MOTION +0.81s 0.00/ -9.93
event6 POINTER_MOTION +0.82s 1.69/ -9.05
When using 2 fingers:
event6 POINTER_AXIS +0.60s vert -9.27* horiz 1.19* (finger)
event6 POINTER_AXIS +0.62s vert -13.25* horiz 2.03* (finger)
event6 POINTER_AXIS +0.65s vert -15.89* horiz 2.03* (finger)
When using 3 fingers:
event6 GESTURE_PINCH_UPDATE +0.68s 4 1.42/-1.54 ( 5.49/-5.97 unaccelerated) 0.99 # 0.15
event6 GESTURE_PINCH_UPDATE +0.71s 4 0.00/-0.31 ( 0.00/-0.89 unaccelerated) 0.99 # 0.07
event6 GESTURE_PINCH_UPDATE +0.73s 4 1.03/-3.44 ( 3.20/-10.74 unaccelerated) 0.98 # 0.74
When using 4 fingers:
event6 GESTURE_SWIPE_UPDATE +0.80s 4 0.00/-0.89 ( 0.00/-6.86 unaccelerated)
event6 GESTURE_SWIPE_UPDATE +0.82s 4 0.00/-1.18 ( 0.00/-7.16 unaccelerated)
event6 GESTURE_SWIPE_UPDATE +0.84s 4 0.68/-3.48 ( 3.20/-16.40 unaccelerated)
So it does seem that there's something on my system that is capable of detecting and reading at least up to four fingers... But for some reason, I can't get them with libevdev...

Trouble implementing crib drag

so I'm enrolled in Stanford's Cryptography class on Coursera and I've been struggling with the first programming assignment (I'm a few weeks behind.)
I've been playing around with different variations of this code for a few weeks to try and remove the issues mentioned below...
At first, I thought I was getting a successful crib-drag, but then I realized a multitude of issues, none of which I've been able to solve:
The "deciphered" results were shortening from the wrong end of the word as the crib is dragged across the XOR of the two cipher texts ("The" > "Th" > "T" instead of "The" > "he" > "e")
The result of crib dragging isn't the text of the other message, but the crib itself...in other words, no matter what crib I choose, the first X number of indices ALWAYS return the crib itself
Here's the code:
def string_xor(a, b):
return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a ,b)])
def manual_crib_drag(word):
with open("two_ciphers.txt", "r") as f:
cipher1 = f.readline()
cipher2 = f.readline()
xor = string_xor(cipher1, cipher2)
word_hex = word.encode("hex")
for x in range(len(xor)):
try:
result = string_xor(xor[x:x+len(word_hex)], word_hex)\
.strip().decode("hex")
print x, ":", result
except TypeError, e: print
Here are the results when running manual_crib_drag("The "):
0 : The
1 : The
2 : The
3 : The
4 : The
5 : The
6 : The
7 : The
8 : The
9 : The
10 : The
11 : The
12 : The
13 : The
14 : The
15 : The
16 : The
17 : The
18 : The
19 : The
20 : The
21 : The
22 : The
23 : The
24 : The
25 : The
26 : The
27 : The
28 : The
29 : The
30 : The
31 : The
32 : The
33 : The
34 : The
35 : The
36 : The
37 : The
38 : The
39 : The
40 : The
41 : The
43 : The?
46 : Tcn$
53 : ??S
71 : PN?
80 : CT"#
83 : ?Q?
88 : `n$
94 : P'e<
99 : U??
118 : b}l
123 : Ǹd?
132 : Tokf
138 : X6%
148 : YW0-
155 : ??4d
161 : ???
171 : ??!
173 : ??d1
177 : Uy?G
200 : hm
202 : de*t
218 : Xn q
238 : Ti0:
249 : 4|5!
253 : i?u
258 : ;G+
263 : t?Qq
269 : )?
275 : t??
282 : Z
285 : G?d
313 : sLtU
319 : !9u?
320 : yo
325 : ?kv0
329 : Gx??
331 : Dﺹ?
For completeness, here are the two cipher texts used in the example:
32510bfbacfbb9befd54415da243e1695ecabd58c519cd4bd2061bbde24eb76a19d84aba34d8de287be84d07e7e9a30ee714979c7e1123a8bd9822a33ecaf512472e8e8f8db3f9635c1949e640c621854eba0d79eccf52ff111284b4cc61d11902aebc66f2b2e436434eacc0aba938220b084800c2ca4e693522643573b2c4ce35050b0cf774201f0fe52ac9f26d71b6cf61a711cc229f77ace7aa88a2f19983122b11be87a59c355d25f8e4
32510bfbacfbb9befd54415da243e1695ecabd58c519cd4bd90f1fa6ea5ba47b01c909ba7696cf606ef40c04afe1ac0aa8148dd066592ded9f8774b529c7ea125d298e8883f5e9305f4b44f915cb2bd05af51373fd9b4af511039fa2d96f83414aaaf261bda2e97b170fb5cce2a53e675c154c0d9681596934777e2275b381ce2e40582afe67650b13e72287ff2270abcf73bb028932836fbdecfecee0a3b894473c1bbeb6b4913a536ce4f9b13f1efff71ea313c8661dd9a4ce
And the result of XORing these two cipher texts is:
PRX]
TS\TW]SW\[\VTS\^W[
TVSPZWSQV
[TZ[P\Q[PZRUS[TVTU[ZUQT[][SZRTWV
h
I'm not sure why it's broken into separate lines, but my guess is that it has to do with spaces in the cipher text XOR result...encasing the return of the string_xor function inside of another join, seems to do the trick though, but because it doesn't seem to affect the results of the crib drag, I left it out of the provided code:
" ".join("".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a ,b)]).split())
I'd appreciate any help! Thanks in advance.
try converting it first to ascii and then do the xor
x = strxor(unhexlify(ciphertexts[0]),unhexlify(target))
print "Ciphertext[0] xor Target\n"
crib = raw_input("Enter Crib:>")
print "Crib\n-->%s<--"%crib
# Crib Drag
for i in range(len(x)):
z = x[i:]
print "\n[%d]"%i
print "%s"%strxor(z,crib)

Resources