Your channel is my very favorite thing that I've found on RU-vid. I would really really appreciate if after modifying your scripts, you could pause for literally one second before saving your file. Throughout the series I've had to pause/unpause as fast as I could to make sure I wasn't missing any changes you made. Huge thanks again for the channel and love your attitude/personality.
For anyone using rizin (fork of radare), the main difference is that you don't specify an address to set a breakpoint at with the "db" command anymore. You have to seek to where you want to set it with "s ", then you can set a breakpoint with "db"
If anyone is reading this later and confused about pointers a good way to understand them a lot better is to go through the arduous process of dynamic memory allocation in C.
Holy crap. Man, finally some really interesting stuff. I really thought that there are a lot videos for beginners in linux or programming, and no videos for middle/senior specialists. That's totally blew my mind. Thanks!
For those who are watching this video with an earlier version of radare2, the use of afvn function changed: Now is "afvn new_name old_name" (Without the quotes)
They should also change the step-over [Shift]+[S] to be the default (without having to hold the [Shift] key pressed). Because it is more frequent (at least for me) to stay at the current level of code than digging into function call tree depth-first :q I can press the [Shift] key when I need to go deeper.
I have some trouble with getting the breakpoints to work. I always get the error "base addr should not be larger than the breakpoint address." After setting the breakpoint with "db 0xEXAMPLE", when I run the program with oop it doesn't stop at the breakpoint. In another crackme, the program stopped at a breakpoint, but that was different from the one I set before, and also I was not able to set the rip afterwards. Can you help me with that?
radare2 comes with a tool to convert values, rax2. So instead of using python you could have done: "rax2 0x394" in another terminal, or even better just run "!rax2 0x394" inside of radare2. Thanks for the tutorials!
practise and fail alott ;) dont be afraid to fail alott. (and do actualy follow the examples, those are ment to be finished, will give you a good feeling instead of directly starting to attack this 1000$ program that has serverside hashing and encryption everytwhere) Its weird that sometimes a simple jmp can make a program be registered.
8:00 where we move "i" the in the EAX register, was so confusing for me untill I understood that RAX is the 64 bit "container" that includes EAX which is the first 32 bit of that "container" and when we move i to EAX, that basically means the same thing as we would move i to RAX since it lives in the same "container" so basically they are the same place, but just refering to different parts of the same place. I initially thought of them as different "containers" for data and thats why I didn't understand this part. I hope my rambling may be of help for somebody. I learnt this from "Learn Assembly Programming - Introduction to Registers" by Daniel Ross if anybody is interested on learning more.
I know you probably are going to answer this in the continuation of the video, but since I had to stop watching because class started, I wanted to ask it before I forget :D: Isn't addition not a good way to do so? because few keys can have the same sum.. That feels like something that has to do with a hash function, if you hash your key, with a good hash function, you're going to hope that each value has a different output, Like in mathematics there's an "Injective function", which means, that : if : (f(x is equals to (f(y Then the only option for that, is if x is equals to y, an Injective function would do the work, but I really think that a this is not that easy to find, and for example, if f(x) is x, then we have to compare it to the string, in the code, which is problematic, because we have to store the string somewhere, so that's kind of a puzzle... Please correct me if I'm wrong, but that's how I understood it, Thanks and have a great day!!
Management: "Make it uncrackable!" Developer: (SMH) Listen we can't make it uncrackable, we can add some countermeasures that may or may not increase the duration in which it takes someone to break into the system. If someone wants in bad enough they will break the system.
12:45 Or instead of reverse engineering the key descramble algorithm, you can just use it in your code to do the hard work for you :) (that is, turn the original program into a keygen).
Just fyi, you don't need to cast a char to int, because in an arithmetical expression it's done so automatically. C converts types lower than int *to* int in calculations.
for those who are getting errors: open your terminal and type the following commands :- gcc license_2.c -no-pie -o license_2 radare2 -zzz license_2 ... and now follow the video and there will be no errors. ; )
in this cas the key = "aaaaaaaaa+" is correct "a" = (97)dec & "+"=(43)dec . (97*9) + 43 = 916 , you must use the regular expression to specify format of key
I know this video was put up 2 years ago, but did you change any settings for radare? Your instructions read as "mov dword [rbp - 0x18], 0" but mine reads as "mov dword [local_18h], 0" in visual mode. This isn't that big of a deal because I still understand and follow along with everything, but I was wondering if this is due to a preference saved/set somewhere or if this is just how the program displays instructions since it's been updated since. I haven't been able to find anything online talking about it.
Pronouncing "array" with the stress on the first syllable... (and "parameter" with stress on 3rd syllable instead of 2nd) Braces on the same line as the block..... No space between operators and operands...! 8 WIDTH INDENTING!!! #triggered Seriously though, good tutorials, enjoyed the vids. :)
Braces on the same line as the block is the only reasonable choice! It saves vertical space, makes the code easier to read, and it’s beautifully aligned with the block instead of being thrown in another arbitrary line.
@@2Pzp It's quite hard to use indentation in text templates :q And it's a pain to edit the indentation after you copy-paste some code from a different place with a different indentation scheme :q Braces? They always work.
so i had some problems setting the breakpoint at 3:30 because radare told me: "Cannot place a breakpoint on 0x00000768 unmapped memory.See e? dbg.bpinmaps". i googled a little bit and found an answer to a stackoverflow question that solved my problem. i had to compile my c program with the flag "-no-pie" to make it an ELF executable. if i dont do that it is an ELF shared object. so my questions are: whats is the difference between a ELF shared object and an ELF executable, how come that error didnt happen to you and is what im doing a sensible solution?
almost. It's not a shared object. PIE (position independent code) is typical for shared objects, but you can also have normal programs compiled with this. basically this means it has full ASLR. So my compiled didn't default to full ASLR (PIE). Shared objects are just like executables, they just miss the entrypoint to actually execute anything. Because they are libraries that can be used by other programs. So it's a binary you can link in your code, and call the functions in that shared object. For example libc is such a shared library.
Is it possible that you had ASLR disabled on your system when you added new breakpoints after reloading with "ood" ? I just spent few hours trying to figure out why all my adresses messed up after ood :D I mean the program can be continued (with dc) and runs normally, but since ASLR kicked in and i guess r2 remembered the old function analysis, i just got "invalid" instructions when pdf. Even "aaa" after "ood" doesn't do anything. so how do you effectively debug PIE binaries with r2? i mean do i have to reload the whole r2 and set my breakpoints again just to rerun the program ? :D also maybe its a bug ( github.com/radare/radare2/issues/13439 ) because even by disabling aslr with rarun2 it just doesn't work and analyses invalid stuff. i'm lost for now lol
It's not that difficult.... kinda. Just make sure some information is missing for the application to function properly. Make people buy or subscribe to user-accounts that hold their data for instance. In terms of encryption, the password is the missing bit that prevents the decryption from returning sensible data. Making sure people don't crack standalone applications is impossible though.
FCore It's kind of impossible to crack.an online service. The best you can so is spend many many hours reverse engineering an entire service solely based on network traffic.which will be useless in the end. No more updates no more support no other users.
FCore When a server is used only for licensing, you're likely not missing any data. I'm talking about a server that is necessary for the client to perform its tasks. Simplest example would be a browser using a webserver
Even a lot of real-time applications need a client-server architecture. The most famous example of real-time client-server examples would probably be any multiplayer game. Tbh, the delay isn't that bad in most cases and you can take a lot of steps to compensate for said delay.
Unless key decrypts stuff then you just inline.... Armadillo first did it years ago with symmetric. Even then just inline key or decryption handler with leaked key
I've got a problem, when i ood like in the third minute, i get a warning message WARNING: bin strings buffer is too big use -zzz or set maxstringbuf when i go on and try to set the breakpoint it says: Cannot place a breakpoint unmapped memory. nevertheless awesome series, keep it up!
i solved it. open your terminal and type the following commands :- gcc license_2.c -no-pie -o license_2 radare2 -zzz license_2 ... and now follow the video and there will be no errors. ; )
Very interesting video as I had always asked myself how keygens actually worked. Now I thought about how to avoid such attempts and came to the following -admittedly naive- idea: Given your key has a length of N characters, divide your key in two chunks we call A and B. Now we calculate the sum of each chunk again, but add some more bloating to conciderably blow up the resulting number. That could for example be done by generating a few permutations of A and B respectively and / or by using some -maybe even dynamic- multiplicator for each characters value. The goal would be to turn both chunks A and B into two huge prime numbers. The check would then be the product of the two numbers, like "if ( A*B == C)". Since by reverse-engineering the program, an attacker could only find C and not the primes used to generate it, wouldn't we essentially force the attacker to reverse-engineer RSA? To make things even harder, A and B could even overlap or be hashed with KECCAK before the bloating, but I am not sure wether we would limit our own choice of valid keys too much by that. After all, if there is only one possible character combination that solves this problem for a arbitrary C, we could ditch the process entirely since each and every customer would get the same key.
Do they still use an explicit "legit or not" branches? I would say integrate the key check (or online validation) with the program itself. Make an encrypted box of memory which is mixed with data, and obscure the exact effect of the key on the operation of the software. It will simply misbehave provided with a wrong key, and finding a keygen would be debugging the entire software. How about that?
On my sandbox, I have radare2 0.9.6. When I do VV, it launches my browser to create the flow graph in graphiz, then loads the web version of radare2. Any idea how to force it to use ASCII graphs? Also, V! doesn't give my any 'boxes', like your view. Any ideas? THanks for the videos.
Hi, I'm new in the domain! I just want to have fun burn key generators for Microsoft products! Can I do that?!? Thanks for taking the time to reply to this comment!
why cant you make the key algorithmic, make the program scramble itself differently based on the different input keys then the key would never even touch the bianary, only the algorithm to scramble the code would
I got confused in one part that deals with rax. When we say rax points to a string and rax+8 is being assigned to rdx. Isn't it pointing to the second character?
This is a bit late 😂. But for anyone else who is struggling with this like I did,it is adding 8 to get to the next input argument in argv, which is the string, then grabbing the character from that string with I. Points to this bit: argv[1][I]
Hi I recently found this channel and I am about 4 years late to the party. As I try to follow the instructions I get stuck at the point where I try to set the breakpoint. It says "Cannot set a breakpoint on unmapped memory." Is it because every-time I re-run r2 in debug mode using "ood" the address changes? Or is there a different reason? Thanks!
I don't have any experience in r2 but this type of problem mostly occurs in gdb because addresses change when you run program so, set a break point on main and after executing...set other breakpoints...
nothing to do with the video but if you really want to make a program uncrackable: for small programs they could be crypted and decrypted at runtime with the serial key as decryption key. To check if the correct key was entered it could be compared in hashed version like most web apps do edit: to me that would be "uncrackable" ... or am i missing something? Ofc. this would only be reasonable for very small programs
Learning basics of ASM Write own "CrackMes" and analyze and crack them through Reversing. Then crack some other CrackMes. Learn Things about Hooks(Detour Functions) And a lots of trial and error ^^
Hi, I’m using a software that has dongle emulator, and also has sentinel ldk, I keep getting sentinel internal error 0x7101, is there a way to remove / bypass sentinel in my software so it works without license? I paid a lot for it for a 3rd party seller who was selling it a hell of a lot less than from original developer, and I feel like he has me by the balls as keeps charging me to fix error... if using ollydbg what do I need to look out for to bypass ?
I'm confused: at 08:15, how does "add rax, rdx" add the start of the array 3 ? I mean, rdx points to the beginning of the text "AAAA-...", and rax points to the argv[1] (I guess), and we are adding the registers directly, which I don't know that is supposed do.
rax first points to argv (not argv[1]). Then you: add 0x8 to rax. After that you load argv[1] into rdx, by doing: mov rdx, [rax]. now in rdx you have a pointer to argv[1]. Then we load the iteratior/counter i into rax. At 8:15 we then add the counter i (rax) to argv[1] (rdx).
ah, now I understand your confusion. You are getting confused by the assembler notation here. "RBP-i" is already renamed to indicate this is the address of the iterator/counter "i". In "reality" the instruction would be something like: mov eax, dword [rbp+0x12] We know that local variables are typically addressed with offsets from the basepointer like: [rbp+0x12] So here in the disassembly you see it being renamed to reflect which local variable it is: [rbp+0x12] -> [rbp-i] In the first line you see a local variable that was not renamed and still has the generic [rbp-local_6]. long story short, that is exactly the line where the value of "i" is loaded into eax.
EAX is RAX. EAX is 32bits of the 64bit wide RAX register. I explain that somehwere :D I would have hoped I did that in this or a previous video - but might also be a later one.
I have some trouble with getting the breakpoints to work. I always get the error "base addr should not be larger than the breakpoint address." After setting the breakpoint with "db 0xEXAMPLE", when I run the program with oop it doesn't stop at the breakpoint. In another crackme, the program stopped at a breakpoint, but that was different from the one I set before, and also I was not able to set the rip afterwards. Can you help me with that?
Commenting again in case anyone else has this problem: I got it to work by re-entering the s sym.main and pdf commands, then doing the breakpoint with the address on the jne
Why wouldnt you just hash the key and compare it with the known hash? Even using MD5 it would seem to be much harder (if not impossible) to bruteforce a long serial key containing numbers and letters.
Keygen in C in case you don't know python. for me key sum was 1330 cuz of different key. #include #include #include int calc_sum(char *str); int random_num(int range); int main(int argc, char *argv[] ){ //Varaibles char str[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"; // All posible character's string char key[300]; // This is where our random key will store. int iter, length_of_key, character_location, True=1; while(True){ // This will decide how long the generated key will be. length_of_key = random_num(strlen(str)-1); // This loop will keep executing untill // we have a key equal to the length of // length_of_key variable. for(iter=0; iter
hey, thanks for this useful video. also can you please make a video on how we can bypass a debugger is detected running in your computor. The software I want to test is protected by VMProtect v5.X. I will be waiting for your response.
Hi, you probably found the solution but I was struggling to find it but I did. At around the 3:00 mark, he converts the hex value he found to decimal, which outputs the 916 key.
Can someone help me at 2:47? I'm good up till then, but once I open the file in radare2, I type aaa and get "cannot find function at 0x00401090 sym. and entry0 (aa)" if I follow his next steps, "s sym.main" the address in the prompt changes to 0x00401176. Then if I type "pdf" and hit enter, it says, "cannot find function at 0x00401176". I did verify that is at 00401176 with objdump, for what it's worth. I also did figure out that I only get this problem if I compile the .c file myself with gcc license_2.c -o license_2, but if i use your binary from github, it works. Why is that?
well i got all the way to 3:33 or so and radare2 doesn't stop at my breakpoint, but continues on to 0x0040064a. after a dc, the rip is at 0040064a. if i set it to 0040064b like in the video, i have to type dc and hit enter twice, and it does end up saying access granted, but obviously, this is not intuitive and as a noob, i really don't understand what going on. probably just updates to r2 since you made this video im guessing...
at8:06 you say we add the i (which is the eax register), to rax. But the assembly instruction is add rax, rdx! And not add rax,eax. So is this a mistake?
rax is the 64 bit version of eax, so they are the same registers, but eax uses 32 bits. So in the line "mov eax, dword [rbp - i]" we are actually setting rax (since eax is the same register, but uses only the last 32 bits). The key is that the cdqe operation makes a 64 bit integer out of the 32 bit integer in eax, which we set to i. So when we add rdx and rax, we are actually adding i to the start of the string.