wrongbaud / hackaday-u Goto Github PK
View Code? Open in Web Editor NEWCourse materials for hackaday.io Ghidra training
Home Page: https://hackaday.io/project/172292-introduction-to-reverse-engineering-with-ghidra
Course materials for hackaday.io Ghidra training
Home Page: https://hackaday.io/project/172292-introduction-to-reverse-engineering-with-ghidra
Hey. Sorry for making this unrelated, but I saw your gba debugging thing and wondered if
you knew how to debug a 3ds with ghidra and luma3ds? I totally understand if this is the
wrong place to ask this.
https://github.com/wrongbaud/hackaday-u/blob/master/README.md
mentions "simple-examples":
simple-examples
: This folder contains simple C programs used to outline certain x86_64 conceptsIs the folder missing or is this a formatting error for the README file?
This is the disassembly I get from Ghidra:
0010072d 48 83 f8 07 CMP length,0x7
00100731 77 0c JA L_LENGTH_OK jump if strlen(argv[1]) > 7
00100733 48 8d 3d LEA argc,[error_length_msg] = "Too short, try again!\r"
64 01 00 00
0010073a e8 61 fe CALL puts int puts(char * __s)
ff ff
L_LENGTH_OK XREF[1]: 00100731(j)
0010073f 48 8b 45 e0 MOV length,qword ptr [RBP + local_28] argv
00100743 48 8b 40 08 MOV length,qword ptr [length + 0x8] argv[1]
00100747 48 89 45 f8 MOV qword ptr [RBP + ptr_input],length
0010074b c7 45 f4 MOV dword ptr [RBP + ptr_index],0x0
00 00 00 00
00100752 c7 45 f4 MOV dword ptr [RBP + ptr_index],0x0
00 00 00 00
00100759 eb 64 JMP L_LOOP_CONDITION
L_LOOP XREF[1]: 001007c3(j)
0010075b 48 8b 15 MOV RDX,qword ptr [XorMe] = DEADBEEFFACECAFEh
ae 08 20 00
00100762 8b 45 f4 MOV length,dword ptr [RBP + ptr_index]
00100765 c1 e0 03 SHL length,0x3 EAX * 8 ( EAX << 3 )
00100768 89 c1 MOV ECX,length
0010076a 48 d3 fa SAR RDX,CL ARITHMETIC SHIFT RIGHT
0010076d 48 89 d0 MOV length,RDX
00100770 88 45 f2 MOV byte ptr [RBP + offset_1],length
00100773 48 8b 15 MOV RDX,qword ptr [globalVar] = 00100868
9e 08 20 00
0010077a 8b 45 f4 MOV length,dword ptr [RBP + ptr_index]
0010077d 48 98 CDQE
0010077f 48 01 d0 ADD length,RDX
00100782 0f b6 00 MOVZX length,byte ptr [length]=>s_KeYpress_00100868 = "KeYpress"
00100785 89 c2 MOV EDX,length
00100787 0f b6 45 f2 MOVZX length,byte ptr [RBP + offset_1]
0010078b 01 d0 ADD length,EDX
0010078d 83 c0 01 ADD length,0x1
00100790 88 45 f3 MOV byte ptr [RBP + offset_2],length
00100793 8b 45 f4 MOV length,dword ptr [RBP + ptr_index]
00100796 48 63 d0 MOVSXD RDX,length
00100799 48 8b 45 f8 MOV length,qword ptr [RBP + ptr_input]
0010079d 48 01 d0 ADD length,RDX
001007a0 0f b6 00 MOVZX length,byte ptr [length]
001007a3 38 45 f3 CMP byte ptr [RBP + offset_2],length
001007a6 74 13 JZ L_NEXT_LOOP
001007a8 48 8d 3d LEA argc,[error_wrong_char_msg] = "Improper character in keycode
09 01 00 00
001007af e8 ec fd CALL puts int puts(char * __s)
ff ff
001007b4 b8 ff ff MOV length,0xffffffff
ff ff
001007b9 eb 1b JMP L_EXIT
L_NEXT_LOOP XREF[1]: 001007a6(j)
001007bb 83 45 f4 01 ADD dword ptr [RBP + ptr_index],0x1
L_LOOP_CONDITION XREF[1]: 00100759(j)
001007bf 83 7d f4 07 CMP dword ptr [RBP + ptr_index],0x7
001007c3 7e 96 JLE L_LOOP
L_SUCCESS
001007c5 48 8d 3d LEA argc,[success_msg] = "Proper keycode supplied, well
24 01 00 00
001007cc e8 cf fd CALL puts int puts(char * __s)
ff ff
001007d1 b8 00 00 MOV length,0x0
00 00
L_EXIT XREF[2]: 00100715(j), 001007b9(j)
001007d6 c9 LEAVE
001007d7 c3 RET
And this is the code generated by the Ghidra's Decompiler:
int main(int argc,char **argv)
{
int ret_code;
size_t length;
int ptr_index;
if (argc == 2) {
length = strlen(argv[1]);
if (length < 8) {
puts("Too short, try again!\r");
}
ptr_index = 0;
while (ptr_index < 8) {
if ((char)((char)((long)XorMe >> ((byte)(ptr_index << 3) & 0x3f)) + globalVar[ptr_index] +
'\x01') != argv[1][ptr_index]) {
puts("Improper character in keycode detected, try again!\r");
return -1;
}
ptr_index = ptr_index + 1;
}
puts("Proper keycode supplied, well done!\r");
ret_code = 0;
}
else {
printf("Please prvide the 8 character keycode");
ret_code = -1;
}
return ret_code;
}
What I don't understand is the 0x3f
logical-and operation (modulo 64) and how should I locate that it should be 0xff
instead, from the disassembled code?
if ((char)((char)((long)XorMe >> ((byte)(ptr_index << 3) & 0x3f)) + globalVar[ptr_index] +
'\x01') != argv[1][ptr_index]) {
Ghidra version:
Thanks in advance.
The skele
binary have remnants of debugging code outputting at which character the key and inputted password mismatchs (and the expected character key) :
The binary should be rebuild from the corresponding source that is properly stripped of the debug code.
In the same vein, i'm not sure the updated build of #7 has been uploaded too.
Once again, thanks for this course (and those sessions 5->8 seems promising too !).
Apart from the issues addressed by the currently unmerged PR #5, I found an undefined behavior issue in pointer-struct.c
which might cause the program to reject valid input.
The issue is that the gen_password()
function allocates and initializes a string to hold the generated password, but it does not add a null terminator:
int gen_password(struct userinfo* info){
int count = strlen(info->username);
int x = 0;
char * pass = malloc(count);
for(x = 0; x < count; x++){
pass[x] = ((char)info->username[x] + (char)info->key)^ (char)info->realKey;
pass[x] = pass[x] - 0x13;
}
info->password = pass;
return 0;
}
The main()
function then calls strlen()
on that string, which is undefined behavior due to the string not being null-terminated:
for(pwordLen = 0; pwordLen < strlen(info.password);pwordLen++ ){
This might cause the loop to iterate too many times, breaking the logic.
edit: Session 3's files
binary suffers from the same issue. However, the source code for it, file.c
, was fixed in this commit, so the binary just needs to be rebuilt.
I see the source code is available for the exercises, it would be great if there were walkthroughs for them too. I know that would require some time but it would be a good stepping stone to use before resorting to looking at the source code.
Either way, cheers for the material!
An amazing course!
Anyway, in session-one/slides/session-1.pdf
,
AH
instead of AL
for 8 bit? after all, EAX
is lower half of RAX
, AX
is lower half of EAX
and AH
is upper half of AX
.RIP
instead of EIP
since we're talking 64-bit.CALL
pushes RSP
, not RBP
.#5
instead of just 5
, as done on other slides?Review how PCode is structured and it's basic definitions
Provide examples of PCode emulation and how to instrument it in Java
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.