Jump to content
Tuts 4 You

Leaderboard


Popular Content

Showing content with the highest reputation since 07/20/2009 in all areas

  1. 27 points
    Hi! This is my first post on tuts4 you I hope that this is the right section, if not, please delete this post! Ok so... Few months ago I have made public my internal project called REDasm on GitHub. Basically it's a cross platform disassembler with an interactive listing (but it's still far, if compared to IDA's one) and it can be extended with its API in order to support new formats, assemblers and analyzers. Currently it supports: Portable Executable VB5/6 decompilation . It can detect Delphi executables, a decompiler is WIP. .NET support is WIP. Debug symbols are displayed, if available. ELF Executables Debug symbols are displayd, if available. DEX Executables Debug symbols are displayed, if available. x86 and x86_64 is supported. MIPS is supported and partially emulated. ARM support is implemented but still WIP. Dalvik assembler is supported. Most common assemblers are implemented by using Capstone library, Dalvik assembler is written manually and even the upcoming MSIL/CIL assembler will be implemented manually. The entire project is written in C++ and its UI is implemented with Qt5, internally, the disassembler is separated in two parts: LibREDasm and UI. LibREDasm doesn't contains any UI related dependencies, it's just pure C++, one day I will split it in two separate projects. Some links with source code, nightlies and wiki: Source Code: https://github.com/REDasmOrg/REDasm Nightly Builds (for Windows and Linux): https://github.com/REDasmOrg/REDasm-Builds Wiki: https://github.com/REDasmOrg/REDasm/wiki And some screenshots:
  2. 23 points
    Hello everyone, Lately I thought it would be good to share some of the stuff I did with Armadillo to the general public, this time it will be about Armadillo’s Stolen Keys feature. When I have some time available, I will update this blog, but in general I don’t like typing long essays so don’t expect too much from that promise. What are stolen keys? Quite obvious, stolen keys are stolen (or otherwise illegally obtained) serials for an Armadillo project. The project developer can maintain a list of these stolen keys and when one of them is entered in the registration dialog it will not be accepted. Very briefly, in Armadillo you have various types of keys and also various key levels. Except unsigned keys (level 0), all keys consist of two parts: [KEYBYTES][sIGNATURE] The signature is the digital signature of the keybytes, this is just to verify the integrity of a key. For this post, only it’s size is of importance. The keybytes also have a variable length. Every serial in Armadillo can store 5 so-called ‘otherinfo’ WORD, 1 date WORD, 1 DWORD (symmetric key) and optionally a keystring. The symmetric key is the key we are looking for when dealing with Armadillo. It is (together with some other constant values) used to decrypt certificate descriptors. These are used to decrypt the program code an optionally the secured sections. Here is a the outline of a key: [ [OTHERINFO][DATE][sYM][KEYSTRING] ][sIGNATURE] As you can see, our target is somewhere near the middle of a key that is fully filled. Luckily, with the correct info, we can strip out the signature, leaving us 1-6 WORDS (otherinfo+encoded date value) and possible a keystring. Before I continue I would like to point out that the stolenkeys are not stored unencrypted in the target file. Every key is encrypted using a simple XOR-encryption with the name bound to the key as seed. Encryption/Decryption goes as follows: char tmp[2048]="";CookText(tmp, name); //UPPERCASE and strip bad charactersunsigned int seed=crc32(tmp, strlen(tmp), NewCRC32); //CRC32 of nameInitRandomGenerator(seed); //Initialize random number generatorfor(int i=0; i<keylength; i++) keybytes[i]^= NextRandomRange(256); NextRandomRange gets a pseudo-random byte in the provided range, in this case a byte. Here is the source code from the random number generator: /* source start */#define m 100000000L#define m1 10000L#define b 31415821L unsigned long a; unsigned long mult(long p, long q){ unsigned long p1=p/m1, p0=p%m1, q1=q/m1, q0=q%m1; return (((p0*q1+p1*q0) % m1) * m1+p0*q0) % m;} void InitRandomGenerator(unsigned long seed){ a=seed;} void NextRandomSeed(){ a=(mult( a, b )+1) % m;} unsigned long NextRandomRange(long range){ NextRandomSeed(); return (((a/m1)*range)/m1);}/* source end */ Attacking Our goal is to find the decryption key of the stolen key. Let’s take a close look at the random number generator. Actually, when we look at NextRandomSeed, we can see one very easily: the final seed is divided by m (100000000) and the remainder becomes the actual new seed. This means that every seed is limited to 99999999 and that is a fairly small amount of brute force attempts! Our goal for today is to write a function, that returns a possible symmetric key from a seed and a piece of data collected from any stolen key (specifically the encrypted symmetric key). Before I start with that I would like to point out that the first two bytes of a stolen key can always be considered junk. This is because either the date, or various otherinfo parameters are always before the symmetric key. In reality, only a maximum of 4 otherinfo parameters is possible (the SoftwarePassport GUI does not have a use for the 5th otherinfo parameter). This means that we would only have to try a maximum of 5 times before we actually find the symmetric key. /* source start */unsigned long NextRandomRangeMod(unsigned int seed){ return (((a/m1)*256)/m1);} unsigned int NextRandomSeed(unsigned int seed){ return (mult( seed, b )+1) % m;} unsigned int decrypt_data(unsigned int seed, unsigned int data){ int next=seed; int res=NextRandomRangeMod(next)<<24; //no little edian next=NextRandomSeed(next); res|=NextRandomRangeMod(next)<<16; next=NextRandomSeed(next); res|=NextRandomRangeMod(next)<<8; next=NextRandomSeed(next); res|=NextRandomRangeMod(next); return res^data;} int main(){ stolen_data=0x????????; for(int i=0; i<m; i++) { unsigned int sym=decrypt_data(i, stolen_data); if(VerifySym(sym)) //imaginary function that checks the sym { printf(“found: %.8X”, sym); break; } }}/* end of code */ Conclusion When implemented in CUDA, brute forcing Armadillo v3-v7.2 goes from ~20 to less than a second. Armadillo v7.4 and higher goes from 2.5-3 hours to 4 minutes! Little tool I created for testing my theories, it actually works! In the attachment I included a DLL that implements the algorithm (and various other Armadillo-related algorithms) with multi-threaded support. I decided not to include the tool because this post is about how it works, not all the tools I created in my life. Last but not least, a hint to the guys at SiliconRealms: do not store (encrypted) keys in a protected file, just store a list of hashes I hope you learned something from this! Greetings, Mr. eXoDia PS If you have any remarks or found a mistake (not related to grammar please), feel free to PM me.
  3. 22 points
    Not going to create a new thread for this, here's present for everyone: Modded de4dot, which supports latest .NET Reactor 4.9.7.0. de4dot-mod-reactor_4.9.zip
  4. 15 points
    Hi guys, after a longer time of coding I would like to share my new app.So with this app you can grab / store / edit / play / record / watch / debug and test play your RTMP streams and much more.In the app I use latest librtmp and it works similar as the rtmpdump commandline tool and you can use also almost all original rtmpdump commands (see synopsis).My main goal was it to build a tool to handle all streams at once in a GUI with a simple and quickly handling.I also added much extra features which should be helpfully to get more needed informations about streams if they don't play (special cases) or if you need to get stream datas manually.All necessary information about the app and features I wrote detailed into included text files and I also created four little videos how to use it and what to do in some special cases specially if you didn't know or worked with rtmpdump before.If yes then its of course a advantage for you. I embedded two file into the app you do need to grab rtmp streams on fly running in your browser.Both files will created (if not present already) if you start the hook.The unhook function does restore original state back if processes are still present.The hook feature works similar as the RTMPDumpHelper tool and it does pipe the traffic to localhost so that rtmpsuck gets it without to record anything and just used to get the stream datas which you then can see in the app to work go on with them.You can use Firefox (flash hook),Chrome or InternetExplorer to use the hook function.The best choice would be Firefox and for Chrome not all sites are working (see video). Embedded Files ------------------------------------- - unpacked rtmpsuck.exe version (disabled record functions) - ConnectHook.dll (coded by me to hook processes) System requirements ------------------------------------- Windows x86 (32 bit) - I coded the app in MASM (WinASM IDE) on Windows 7 and didn't test it on lower systems like XP now etc. - Installed VLC player - Firefox or Chrome or Internet Explorer browser Optional: SWF ID (Check for running flash player / Chrome / IE / download for HMAC check) JPEXS Decompiler (Find secureToken or custom command etc) RTMP Store and Play 1.0 + Videos.rar PS: Have fun with my app and maybe you will like to use it in the future so I tried my best (as good as possible for me) to create a simple and good alternative free app. Feedback or possible bugs reports etc are welcome of course. greetz
  5. 15 points
    Some reasons I'd say that have helped slowly kill the scene, albeit not fully dead but definitely not where it was before: Money - Given that it's much easier to obtain money online via ePayments such as Paypal, Stripe, etc. people are more inclined to stop sharing things for free and instead expect money for their time/work. Nothing wrong with this expect for when it ties into another issue, copy-pasting. Copy-Pasting - Something that has definitely become a huge issue with anything released related to hacking/reversing etc. is that things turn into a copy/paste fest these days. Before, the scene was strict about monitoring for ripping of content and calling out teams/people for things when they were caught. However, now it is so widespread and there is no real sense of respect like before so there is no quality control any longer. (A prime example of this, HackForums. It is nothing but a skid copy/paste fest on that site. There are a few decent coders but the vast majority just copy others stuff, change 1-2 lines of code, rename the project and claim they wrote it. Another example, ConfuserEx, look at all the different 'modded' versions of it that change little to nothing but claim its a fully new protection.) Ego/Attitude - Another thing that has become more of a problem, in my opinion, is the expectation that anyone new to reversing is supposed to just know everything off the bat and otherwise gets flamed asking for help. This is something that has affected this site over the last few years with anyone asking for assistance getting bitched at for no reason. Something that seems to be forgotten by some of the experienced people is that they started off not knowing anything at one point too and instead they just enjoy being assholes to others. Hence why the challenges section of this site have gone under a ton of changes since it just turned into a 'look at my e-dick' fest for a while. Overall though, times have changed, people pay for things more readily than waiting for anything free to come out first. People pay for cracks/exploits/0days/etc. with some paying for large amounts of money. It incentivizes those capable to sell their work instead of releasing it for free and having it ripped within a week. Don't blame them, to be honest either, with sites like HF, copypasting is such a huge problem anymore.
  6. 14 points
    Hi, I made a tool that interprets a vmp rsi-stream, it records the handlers (or vm instructions) and connects them via their data dependencies. This is how a JCC looks like The edges in this graph represent data dependencies. Sequences of nodes with one input and one output are collapsed into blocks. Green nodes are constant nodes. They do not depend on external values (such as CPU registers), unlike red nodes. The hex number left of a node is a step number, the right number is its result. Only const nodes (green) can have a result. The graph contains all nodes that directly or indirectly contribute to the lower right "loadcc" instruction. CMP/JCC in VMP works by executing an obfuscated version of the original CMP which also results in either zero or one. VMP then pushes 2 adresses to its stack (step 121f and 1209) and computes an address that points to either one, depending on zero/one result of the corresponding CMP (step 1265). It then simply loads from that computed address and uses its value for a JMP. The load that loads either address is represented by the "loadcc" node in the graph. Even though all puzzle pieces are here, it is still hard to figure out what the original CMP was, but luckily we have LLVM and luckily it isn't hard to lower the graph to LLVM IR: Godbolt Left is the graph as LLVM IR, middle is output of the optimizer, right is the optimized LLVM IR lowered to x64. The attachment contains the original x64 input, the complete vmp program as LLVM (not just the loadcc part), the optimized x64 (-O3) and an unoptimized version (-O0). The unopt version is interesting because it shows how vmp looks like after removing the junk but still leaving the handlers intact (RSI access is removed, RBP-stack is pre-baked to make it easier for the optimizer passes) I thought it was pretty impressive how LLVM's optimizer plows through the crap and produces such a beautiful result. That is all. Thanks for reading. testproc.zip
  7. 14 points
    I wish to all the community an happy Christmas. Enjoy your time with your loved ones, hope the new year will bring happiness to everybody.
  8. 14 points
    Hello community, I know you all do expect the paper that I announced about Enigma 2.x unpacking but I don't know when or if I will ever finish it. Because I don't want this project I spent so much time on to die, I decided to publish the source code of it now and seperate from the paper so that everyone can prepare it for future Enigma versions. Also LCF-AT found a bug that I couldn't fix so quickly so I hope someone who is more advanced in c++ than me can fix it. See http://forum.tuts4you.com/topic/26896-the-enigma-protector-2xx-unpacking-devirtualizer-by-dizzy-d/page__st__20#entry135147 for details. Just compile the source with MSVC++2010 and everything should work. Enigma DeVirtualizer.rar
  9. 13 points
    Hi Guys and here is my solution for 32bit one. devirtualizeme32_vmp_3.0.9_v1_deVM_Raham.zip PS: my decompiler is in progress state, so tell me if you found mistake in X86 instructions. Kind Regards
  10. 13 points
    This forum and many others got overrun by lazy n00bs who think running de4dot makes them reversers. Consequently, skilled guys moved to semi-private places (or got hired by security-related companies) and stopped sharing their knowledge with general public. Sad but true.
  11. 13 points
    Tutorial: 1. MegaDumper, get ResourceAssembly.dll (assembly than contains resources) 2. Use ConfuserDelegateKiller to remove delegates from UnpackMe.exe (google it) 3. de4dot with parameters (-p un --strtyp delegate --strtok 06000043) 4. CryptoObfuscator constant fixer by me (pm if you need) 4. Remove all instructions from <Module>.cctor 5. Attach resources with ResourceManager (use file from step 1) 6. Clean from junk classes and delegates
  12. 13 points
    Some steps to get the real file, deobfuscating it will be up to you though: Finding The Embedded Resource Name Open the crackme in your favorite PE browser.View the file resources.Locate RCDATA and find the main resource. In this case it is "__"Dumping The "Real" ExecutableOpen the crackme in OllyDbg.Find all string references and look for the resource name we just found. In this case: Cra'ckMe.0041B280 ; UNICODE "___"Follow the reference into the code.Scroll down and locate the calls to 'SafeArrayCreate' and 'SafeArrayAccessData'. These are the important calls we want to find.We want to set a breakpoint on the call after SafeArrayAccessData. (See code below)Once the break is hit, step over the call.Follow EAX in the dump window. This is the executable decrypted from the "__" resource.Save the memory region, do any fixes needed based on how you save the region etc.You should now have the real executable.004022D9 |. 8D8C24 8800000>LEA ECX,DWORD PTR SS:[ESP+0x88]004022E0 |. 51 PUSH ECX004022E1 |. 6A 01 PUSH 0x1004022E3 |. 83C5 F2 ADD EBP,-0xE004022E6 |. 6A 11 PUSH 0x11004022E8 |. 89AC24 9400000>MOV DWORD PTR SS:[ESP+0x94],EBP004022EF |. 899C24 9800000>MOV DWORD PTR SS:[ESP+0x98],EBX004022F6 |. FF15 54B14100 CALL DWORD PTR DS:[<&OLEAUT32.#15>] ; OLEAUT32.SafeArrayCreate004022FC |. 8D5424 48 LEA EDX,DWORD PTR SS:[ESP+0x48]00402300 |. 8BF0 MOV ESI,EAX00402302 |. 52 PUSH EDX00402303 |. 56 PUSH ESI00402304 |. 895C24 50 MOV DWORD PTR SS:[ESP+0x50],EBX00402308 |. FF15 58B14100 CALL DWORD PTR DS:[<&OLEAUT32.#23>] ; OLEAUT32.SafeArrayAccessData0040230E |. 8B4424 48 MOV EAX,DWORD PTR SS:[ESP+0x48]00402312 |. 55 PUSH EBP00402313 |. 57 PUSH EDI00402314 |. 50 PUSH EAX00402315 |. E8 36900000 CALL Cra'ckMe.0040B350 <=========== SET BREAKPOINT HERE0040231A |. 83C4 0C ADD ESP,0xC0040231D |. 56 PUSH ESI0040231E |. FF15 5CB14100 CALL DWORD PTR DS:[<&OLEAUT32.#24>] ; OLEAUT32.SafeArrayUnaccessDataDumping The "Real" Real ExecutableOpen the new file you dumped in a .NET disassembler such as ILSpy.View the files managed resources and save the resource '_' in this case, to disk as a new executable.This new file is the real obfuscated crackme file fully removed from the loaders.After this point I stopped, the file does a lot of suspicious things so I didn't bother continuing.
  13. 12 points
    Every once in a while someone is asking about working in RE-related field - what it's like, how to start, what to study, etc. I personally think this is a good summary: https://medium.com/@laparisa/so-you-want-to-work-in-security-bc6c10157d23
  14. 11 points
    Ransomware is very common these days. Once it installs on a user machine it begins encrypting files. When the user comes to know about the ransomware attack it is already too late. Unless the user has a backup, he/she must must pay the ransom to recover the files. Luckily there has been cases where due to a faulty implementation of cryptography breaking such malware becomes feasible. The recently discovered petya ransomware is an example. This blog post is a short walk through on breaking the petya ransomware with a constraint solvers. Hope you like it & find useful. http://0xec.blogspot.com/2016/04/reversing-petya-ransomware-with.html
  15. 11 points
    LoaderCSharp: Loader C# source code, It will search in memory for hex string and will replace with another hex string. Maybe somebody will find it usefull. LoaderCSharp.zip
  16. 11 points
    Today I wrote a small class that assists with patching .NET binaries. using System; using System.IO; using dnlib.DotNet; using dnlib.DotNet.Emit; namespace MyNamespace { class Patcher { public delegate bool PatchStrategy(AssemblyDef asm); private static bool patchMethodReturnBool(AssemblyDef asm, string classPath, string methodName, bool returnValue, int numArguments = 0) { var method = findMethod(asm, classPath, methodName); if (method != null && method.Parameters.Count == numArguments) { //patch instructions var instructions = method.Body.Instructions; if (returnValue) instructions.Insert(0, OpCodes.Ldc_I4_1.ToInstruction()); //true else instructions.Insert(0, OpCodes.Ldc_I4_0.ToInstruction()); //false instructions.Insert(1, OpCodes.Ret.ToInstruction()); return true; } return false; } private static MethodDef findMethod(TypeDef type, string methodName) { if (type != null) { foreach (var method in type.Methods) { if (method.Name == methodName) return method; } } return null; } private static MethodDef findMethod(AssemblyDef asm, string classPath, string methodName) { return findMethod(findType(asm, classPath), methodName); } private static TypeDef findType(AssemblyDef asm, string classPath) { foreach (var module in asm.Modules) { foreach (var type in module.Types) { if (type.FullName == classPath) return type; } } return null; } public static bool PatchAssembly(string path, ref string error, PatchStrategy patcher) { var bakpath = path + ".bak"; try { //handle backup if (!File.Exists(bakpath)) File.Copy(path, bakpath); else File.Copy(bakpath, path, true); } catch (Exception x) { error = x.ToString(); return false; } try { DateTime creationTime = File.GetCreationTime(path); //load module var module = ModuleDefMD.Load(File.ReadAllBytes(path)); //execute patching strategy if (!patcher(module.Assembly)) return false; //write assembly if (module.IsILOnly) module.Write(path); else module.NativeWrite(path); //restore file date File.SetLastWriteTime(path, creationTime); File.SetCreationTime(path, creationTime); return true; } catch (Exception x) { File.Copy(bakpath, path, true); error = x.ToString(); } return false; } } } For every patch you write a strategy like this: public static bool PatchRegistrationCheck(AssemblyDef asm) { string classPath = "MyNamespace.MyClass"; /* * public bool IsRegistered(RegistrationData rd) * { * return true; * } */ if (!patchMethodReturnBool(asm, classPath, "IsRegistered", true, 2)) //2 parameters (this + rd) throw new Exception("MyClass.IsRegistered not patched!"); return true; } Then you call it like this: Patcher.PatchAssembly(filePath, Patcher.PatchRegistrationCheck); Hope it will be useful for some of you. Greetings
  17. 11 points
    Because they're open source? One advantage of an open source obfuscator is that you can modify the algorithms and add other stuff to prevent tools from working. Did you know that there are more deobfuscators for commercial obfuscators than for open source obfuscators? There's no obfuscator that offers any real protection, they just slow down the inevitable: your competitor will copy your code or someone will crack your app.
  18. 11 points
    flag{Y0u_s0lved_that_r1ght!!!} EDIT: I enjoyed it so much that I think it deserves a small writeup. Coming up in few hours..
  19. 11 points
  20. 10 points
    - version 4.0: 1- add RegexSearch form. 2- New GUI after replace DataGridView with RichTextBox to easy deal and fast coding. 3- edit CustomBuildStep to Auto copy files (AdvSconfig.txt , HelpAdvancedScript.txt). 4- add AutocompleteMenu.dll . 5- add copy AutocompleteMenu.dll to x64dbg root . 6- add AdvSconfig.txt for AutoComplete list for define Commands and variables. 7- update AutocompleteMenu.dll. 8- add comments_ to Variables class to add it next to the description of the variables when call them by Ctrl+j 9- call list var's by Ctrl+j 10- add ReFill_FunctionsAutoComplete_AtLoad. 11- highlight_system done for good look and analyze. 12- add autoCompleteFlexibleList to handle commands defined in AdvSconfig.txt. 13- add open Script from out side. 14- refresh by menu and F5 to refresh highlight_system. 15- add var of x64dbg system. note : by AdvSconfig.txt u can define the commands in AdvancedSecript . AdvancedScript_4.0.zip
  21. 10 points
  22. 10 points
    @whoknows: why would I lie? And my answer was there 1 hour before CodeCracker's answer.. Short tutorial: 1. Olly + ScyllaHide takes care of all anti-debug. So I didn't have to worry about that; 2. Load ggggg.exe in DNSpy and look around. You'll see what methods are there, their arguments and so on. Interesting parts are: internal static extern bool StrongNameSignatureVerificationEx([MarshalAs(UnmanagedType.LPWStr)] string wszFilePath, bool fForceVerification, ref bool pfWasVerified); This is obviously anti-debug measure. It's good that we have a method that's called via P/Invoke because it's easy to put a breakpoint on it.. private delegate void proStatusCallback(double val, string fl, string flSize); This tells us that some things will (probably) be asynchronous. Hardware breakpoints are different for each thread, you can't use those! Use memory breakpoints instead. private void <Module>(object sender, EventArgs e) Method with those parameters is usually control_onClick.. So, most likely called when you click "Validate" button. Not that it matters.. 3. Load ggggg.exe in Olly. Put breakpoint on StrongNameSignatureVerificationEx. 4. Enter whatever serial and click Validate. Olly will break. 5. Step out of Windows API and CLR methods until you arrive at JIT'ed code. 6. Now the hard work begins. Debug the code and make comments what each JIT'ed method does. Eventually you'll arrive here (addresses and the exact code will be different, depending on OS/.NET Framework version/etc.): 005411AD 8BF1 MOV ESI,ECX 005411AF 8BFA MOV EDI,EDX 005411B6 817D 08 7A040000 CMP DWORD PTR SS:[EBP+8],47A 005411BD 75 13 JNZ SHORT 005411D2 005411BF FF75 0C PUSH DWORD PTR SS:[EBP+C] 005411C2 8BCE MOV ECX,ESI 005411C4 8BD7 MOV EDX,EDI 005411C6 FF15 888C4F00 CALL DWORD PTR DS:[4F8C88] 005411CC 5E POP ESI 005411CD 5F POP EDI 005411CE 5D POP EBP 005411CF C2 0800 RETN 8 There's a check for constant 0x47A. Depending on the entered serial , value at [EBP+8] changes. So it's some sort of checksum. 7. Figure out a serial which passes this check. I found "9999999k" 8. Now you can go further.. Call at address 5411C6 has one argument on stack - entered serial number. So, this must a be a very interesting method. 9. Put memory breakpoint on the argument in stack, run and breakpoint will hit inside mscorlib. Step out until JIT'ed code and you'll be somewhere here: 003C1377 8BC8 MOV ECX,EAX 003C1379 8BD6 MOV EDX,ESI 003C137B 8B01 MOV EAX,DWORD PTR DS:[ECX] 003C137D 8B40 34 MOV EAX,DWORD PTR DS:[EAX+34] 003C1380 FF50 04 CALL DWORD PTR DS:[EAX+4] <--- this converts unicode string to byte array. Memory breakpoint triggered inside it. 003C1383 8BCF MOV ECX,EDI 003C1385 8BD0 MOV EDX,EAX 003C1387 3909 CMP DWORD PTR DS:[ECX],ECX 003C1389 E8 82BAB771 CALL mscorlib.71F3CE10 003C138E 8945 EC MOV DWORD PTR SS:[EBP-14],EAX 003C1391 B9 34380072 MOV ECX,72003834 10. Next call (at 003C1389) returns array of 0x10 bytes.. 025849E8 48 44 00 72 10 00 00 00 38 D0 8E 21 6C D5 23 66 HD.r...8ÐŽ!lÕ#f 025849F8 70 56 45 B9 5A 99 41 7F pVE¹Z™A Could it be that "38D08E216CD52366705645B95A99417F" == MD5("9999999k")? Quick google search confirms that. 11. Breakpoint on byte array, run. See byte array converted to hex string. Breakpoint on string, run.. See 2 strings being compared. 12. Google for the 2nd string. It's MD5("tarkus"). Problem solved.
  23. 10 points
    Don't even believe him, guys I will list some of the things he really did: 1) He jumped into the project and boosted it 100x, ported the code from VMP64 to VMP32, fixed bugs, added new features! 2) The file was cleaned and repackaged entirely by him! 3) He boosted my research every single time I shared with him the work I was doing well before joining the project. 4) He also suggested some nice music to listen to that's true. Useless to say we still have plenty of research to do.
  24. 10 points
    Hey all, recently I came across some old source code from me again for an OllyDbg Deobfuscator Plugin, so I decided why not share it as well. I wanted to improve it and use emerged librarys but that was just a hobby and I haven't found time again for it. Maybe the code can help someone working on x86 deobfuscation and that kind of stuff to get some ideas... OllyDeobfuscator.rar
  25. 10 points
    Identifying Malicious Code Through Reverse Engineering Link: http://download.adamas.ai/dlbase/ebooks/VX_related/Identifying%20Malicious%20Code%20Through%20Reverse%20Engineering.pdf
  26. 10 points
    File Name: final fantasy File Submitter: Dreamer File Submitted: 24 Feb 2014 File Category: uPPP Skins Click here to download this file
  27. 9 points
    It's a really nice challenge, thank you! Pseudo-solution: Step 1: make type/function/variable names readable. De4dot to the rescue. Step 2: get some idea how the VM works. In this case, we have P-Code stored in MemoryStream and stream.Position tells us which instruction we're currently executing (aka. EIP). Step 3: put some smart breakpoints and trace execution of the VM. We're looking for good boy/bad boy jumps, so focus on changes in stream.Position. I put a breakpoint in UnmanagedMemoryStream.Seek: Step 4: look at the log data and identify good boy/bad boy jump. In my case, logged data with some comments looked like this. So, we need to trace few instructions starting from EIP=16F4. Turns out that comparison instruction is at EIP=172B and good boy jump is EIP=173D. Step 5: patch P-Code or VM engine. I decided to patch P-Code directly, as integrity checks for the P-Code were not enabled. I changed comparison instruction to compare 2 identical values, so the check always succeeds and good boy jump is always taken. Mission accomplished. EDIT: attached file should not be in the middle of sentence. Out-patched-by-kao.zip
  28. 9 points
    There you can find awesome articles on how to face FinSpy VM: http://www.msreverseengineering.com/blog/2018/1/23/a-walk-through-tutorial-with-code-on-statically-unpacking-the-finspy-vm-part-one-x86-deobfuscation https://www.welivesecurity.com/wp-content/uploads/2018/01/WP-FinFisher.pdf Credits to Rolf Rolles and Filip Kafka
  29. 9 points
    Just some small code I created for a friend. Not stress-tested or anything, might be useful though #include <windows.h> #include <stdio.h> int gtfo(const char* text = "") { printf("gtfo! (%s)\n", text); return -1; } int main(int argc, char* argv[]) { //LEAKY AND UNSAFE! if (argc < 2) return gtfo("argc"); //read the file auto hFile = CreateFileA(argv[1], GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); if (hFile == INVALID_HANDLE_VALUE) return gtfo("CreateFile"); //map the file auto hMappedFile = CreateFileMappingA(hFile, nullptr, PAGE_READONLY | SEC_IMAGE, 0, 0, nullptr); //notice SEC_IMAGE if (!hMappedFile) return gtfo("CreateFileMappingA"); //map the sections appropriately auto fileMap = MapViewOfFile(hMappedFile, FILE_MAP_READ, 0, 0, 0); if (!fileMap) return gtfo("MapViewOfFile"); auto pidh = PIMAGE_DOS_HEADER(fileMap); if (pidh->e_magic != IMAGE_DOS_SIGNATURE) return gtfo("IMAGE_DOS_SIGNATURE"); auto pnth = PIMAGE_NT_HEADERS(ULONG_PTR(fileMap) + pidh->e_lfanew); if (pnth->Signature != IMAGE_NT_SIGNATURE) return gtfo("IMAGE_NT_SIGNATURE"); if (pnth->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) return gtfo("IMAGE_FILE_MACHINE_I386"); if (pnth->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC) return gtfo("IMAGE_NT_OPTIONAL_HDR_MAGIC"); auto importDir = pnth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; puts("Import Directory"); printf(" RVA: %08X\n", importDir.VirtualAddress); printf("Size: %08X\n\n", importDir.Size); if (!importDir.VirtualAddress || !importDir.Size) return gtfo("No Import directory!"); auto importDescriptor = PIMAGE_IMPORT_DESCRIPTOR(ULONG_PTR(fileMap) + importDir.VirtualAddress); if (!IsBadReadPtr((char*)fileMap + importDir.VirtualAddress, 0x1000)) { for (; importDescriptor->FirstThunk; importDescriptor++) { printf("OriginalFirstThunk: %08X\n", importDescriptor->OriginalFirstThunk); printf(" TimeDateStamp: %08X\n", importDescriptor->TimeDateStamp); printf(" ForwarderChain: %08X\n", importDescriptor->ForwarderChain); if (!IsBadReadPtr((char*)fileMap + importDescriptor->Name, 0x1000)) printf(" Name: %08X \"%s\"\n", importDescriptor->Name, (char*)fileMap + importDescriptor->Name); else printf(" Name: %08X INVALID\n", importDescriptor->Name); printf(" Name: %08X\n", importDescriptor->Name); printf(" FirstThunk: %08X\n", importDescriptor->FirstThunk); auto thunkData = PIMAGE_THUNK_DATA(ULONG_PTR(fileMap) + importDescriptor->FirstThunk); for (; thunkData->u1.AddressOfData; thunkData++) { auto rva = ULONG_PTR(thunkData) - ULONG_PTR(fileMap); auto data = thunkData->u1.AddressOfData; if (data & IMAGE_ORDINAL_FLAG) printf(" Ordinal: %08X\n", data & ~IMAGE_ORDINAL_FLAG); else { auto importByName = PIMAGE_IMPORT_BY_NAME(ULONG_PTR(fileMap) + data); if (!IsBadReadPtr(importByName, 0x1000)) printf(" Function: %08X \"%s\"\n", data, (char*)importByName->Name); else printf(" Function: %08X INVALID\n", data); } } puts(""); } } else puts("INVALID IMPORT DESCRIPTOR"); return 0; } Greetings
  30. 9 points
    here's my tutorial, https://es.scribd.com/doc/249946274/Unpack-Jar2Exe Unpack Jar2Exe.pdf
  31. 9 points
    Unpacked UnpackMe_unpacked.zip
  32. 9 points
    Hello everyone,Together with cypher I started working on an update for the famous TitanEngine. The main intention for the 'community edition' is bugfixing, but there are also several features added. We want to keep the original function names and arguments of TitanEngine v2, but in some cases the function arguments were for example incompatible with 64-bit systems. Various changes: Fixed hardware breakpoints (various problems in x32 and not working in x64);Fixed memory breakpoints (still needs some checks);Changed exception handling (now only non-debugger-handled exceptions are reported);Fixed TitanEngine64 (never started debugging);Pieces of code rewritten;Fixed DumpProcessExW (found/fixed by Aguila);Added various callbacks (SetCustomHandler);Added memory breakpoint on execute;Added QWORD hardware breakpoints;Smaller and cleaner DLL Loaders (written in NASM);Support for multiple calling conventions (TITCALL), default changed to _cdecl;MinGW import libraries (for compatibility with x64_dbg);Fixed exception handling;Import reconstruction -> Scylla (cypher);Various other bugfixes too small to mention;StepOver calls StepInto when needed (RET, JMP, REP).StepInto calls StepOver when needed (PUSHFD)Find downloads on the repository. Please report bugs/feature suggestions in another thread in this forum. If you want to contribute, just send me and/or cypher a private message. Greetings, Mr. eXoDia & cypher
  33. 8 points
    I created a spinner type control to add to the ModernUI controls (based on an my original version a few years ago: http://masm32.com/board/index.php?topic=1179.0) - typically used when loading, pre-loading or processing something and to hint or indicate to the user something is occurring - similar in that regard to progress bar controls. Download The control can be downloaded via the ModernUI repository or downloaded directly from this link: https://github.com/mrfearless/ModernUI/blob/master/Release/ModernUI_Spinner.zip?raw=true Example I created an example project to demonstrate it. The example (which includes a Radasm project) can be downloaded via the ModernUI repository or downloaded directly from this link: https://github.com/mrfearless/ModernUI/blob/master/Release/MUISpinner1.zip?raw=true There are a number of ways of adding image frames to the ModernUI_Spinner control. The most basic level is to add individual images to construct the spinner animation. This can be done with the MUISpinnerAddFrame or MUISpinnerLoadFrame - using an image handle that is already loaded or using a resource id of an image. For example, the first spinner it is comprised of 8 separate bitmap images: For images that are circular, it can be more convenient to use the MUISpinnerAddImage or MUISpinnerLoadImage functions, as these only require one image. The image is copied a number of times into frame images - as specified by the dwNoFramesToCreate parameter. Each new frame image is incrementally rotated - based on the angle calculated for each new frame image. The bReverse parameter if set to TRUE will set the spinner animation to counter-clockwise. Note: the MUISpinnerAddImage or MUISpinnerLoadImage functions only work with png images or png's stored as RCDATA resources. The far right spinner on the top row is created via loading a single png image: Once loaded it is rotated and new frames are created to enable it to look like this: For more complicated spinners, or spinners that are not circular in nature, the MUISpinnerAddSpriteSheet and MUISpinnerLoadSpriteSheet functions are provided. These allow you to provide a long (wide) image (bitmap, icon or png) handle (or resource id) that contains all the spinner frames in the one image. The image frames are extracted out of this image. The amount of frame images in the spritesheet is passed via the dwSpriteCount parameter. The clock spinner is a good example of this, as it can't be rotated due to the buttons around its edge: So either it can be constructed by manually adding each frame or by using a spritesheet like so: Which looks like this once all the individual frames are extracted: I put some compile time conditions to allow for using of TimerQueue, Multimedia Timer or WM_TIMER for the animation of the spinner. There is also a ModernUI_Spinner.h file for c/c++ - but as I don't actively use that language there may be some typos or mistakes or wrong types specified (I haven't tested it). The Icons8 website is a good source for spinners, and they can be adjusted for size and color etc before downloading - including under the additional download options button as a spritesheet (using apng format). Take note of the frames value, as you will need to use this so that the spritesheet can be divided up into the correct individual frames. https://icons8.com/preloaders/en/search/spinner
  34. 8 points

    11,699 downloads

    Many of you may be amazed at Guru LCF-AT's script "VMProtect API Turbo Tracer 1.2". But for most of the newbies, just like me, you may have a lot of problems in getting the script work properly in your own Ollydbg. LCF-AT already uploaded a lot of Ollydbg setting information togehter with the script to help us fix those Ollydbg problems, but there are too many details. Yes, I suffered a lot at the inital stage when I was trying to use "VMProtect API Turbo Tracer 1.1" by my chinese version "Terminator Ollydbg 1.1.0". Under LCF-AT's kind help, I created this basic version Ollydbg 1.1.0, which is specially for running "VMProtect API Turbo Tracer 1.1". And it works smoothly in my laptop, with Windows XP Professional SP3. If you like, get it and give it a try. Enjoy Cracking!!
  35. 8 points
    Hello All 😁 this's my first post in Tuts 4 You , Hope it won't be the last 😅 Cmulator is ( x86 - x64 ) Scriptable Reverse Engineering Sandbox Emulator for shellcode and PE binaries Based on Unicorn & Capstone Engine & javascript . https://github.com/Coldzer0/Cmulator this's a work of 3 months , and the Development is Active , the project is fully written in FreePascal 😎 i'm planning to port the project "C" so it last longer ( so we get more contributors ) . Hope you find it useful
  36. 8 points
    A plugin to copy a selected disassembly range in the x64dbg cpu view tab and convert to a masm compatible style assembler code and output to clipboard or the reference view tab. Features Copy selected range to assembler style code. Outputs assembler code to clipboard or reference view. Adds labels for jump destinations. Adjusts jump instructions to point to added labels. Indicates if jump destinations are outside selection range. Code comments to indicate start/end and outside range. Options to adjust comments and label outputs. Format hex values as C style (0x) or Masm style. Registered commands: CopyToAsmClip (ctac) and CopyToAsmRef (ctar) How To Install Copy the CopyToAsm.dp32 file to your x64dbg\x32\plugins folder Copy the CopyToAsm.dp64 file to your x64dbg\x64\plugins folder How To Use Open x64dbg Open target Select lines of disassembly in the cpu tab window Select CopyToAsm plugin Select copy to clipboard (or copy to reference view tab) Paste into text document (if previously copied to clipboard) Project Pages https://github.com/mrfearless/CopyToAsm-Plugin-x86 https://github.com/mrfearless/CopyToAsm-Plugin-x64 Downloads CopyToAsm-Plugin-x86 CopyToAsm-Plugin-x64 Some screenshots See wiki example for more details: szLen example Raw x64dbg disassembly of szLen function of masm32 library: Copied and processed asm code pasted to clipboard:
  37. 8 points
    Here is the devirtualized code. Keygenning this will be quite a effort. I will give it a try nevertheless. vm.rar
  38. 8 points
    Makes for a bit of an interesting read... http://cturt.github.io/ps4.html Ted.
  39. 8 points
    you must understand the IL code. of course you cannot start with Confuser ex 5 to start, download phoenix by daniel pistelli, and try to protect a program. manual deobfuscation is not something complex, you have just to analyze the IL code, read the ECMA 335 or ISO/IEC 23271:2012 the way to learn is practice and interest. btw, i wrote a tutorial some tme ago about how to decrypt constants manually. .NET Decrypt constants manually using PowerShell1.pdf
  40. 8 points
    I posted the writeup here: http://lifeinhex.com/sniffing-correct-serial-in-net-crackmes/ - here's a (badly formatted) copy-paste. Introduction In this tutorial I’ll show you a generic way how to break most of the crackmes written in VB.NET. It uses the fact that most crackmes made by beginners will calculate correct serial and do a simple comparison “if enteredSerial = correctSerial then”… To break such a crackme, you only need to find this comparison and sniff the correct serial. This is a very common approach in x86 world but in .NET world it’s not that popular yet. As for my target, I’m using “RDG Simple Crackme .NET v4 2015” GetProcAddress in .NET In x86 world you can use GetProcAddress function to get address of any API function from any DLL. Can we do something similar in managed environment like .NET? It turns out that we can, but it’s a little bit harder. So, for example, to get address of Assembly.Load(byte[]) you need to do: MethodBase mb = typeof(Assembly).GetMethod("Load", new Type[] { typeof(byte[]) });IntPtr handle = mb.MethodHandle.GetFunctionPointer();Console.WriteLine("Assembly.Load() = {0:X}", handle.ToInt32()); This works well with static classes and static methods. How about non-static methods like RijndaelManaged.CreateDecryptor(byte[], byte[])? That’s doable as well, like this: RijndaelManaged rijndael = new RijndaelManaged();mb = rijndael.GetType().GetMethod("CreateDecryptor", new Type[] { typeof(byte[]), typeof(byte[]) });handle = mb.MethodHandle.GetFunctionPointer();Console.WriteLine("RijndaelManaged.CreateDecryptor() = {0:X}", handle.ToInt32()); To make this reference almost complete – here’s how to get address of .ctor: ConstructorInfo ctor = typeof(MyClass).GetConstructor(Type.EmptyTypes);IntPtr ctorPtr = ctor.MethodHandle.GetFunctionPointer();Console.WriteLine("MyClass constructor = {0:X}", ctorPtr.ToInt32()); There are a few gotchas, however.. In case your target type is located in assembly that’s not NGEN’ed yet, I suggest that you use ngen and install the assembly in cache. That can prevent certain problems later.Addresses of functions are obviously different in .NET 2.0 and 4.0. You must compile for correct framework version and target the correct .NET assembly.Addresses of functions are different for x86 and x64 framework versions, too. Make sure your assembly is compiled correctly.Sniffing string compareSuprisingly, string comparison in VisualBasic.NET and other .NET languages is different. It’s caused by Option Compare statement present in Visual Basic language. So, if the crackme is made in VB.NET, you need to examineOperators.CompareString(string,string,bool) function. For crackmes made in other languages, you’ll need to examine string.Equals(string) or some other variation of this method. So, using the code I mentioned above, I learned that address ofOperators.CompareString(string,string,bool) on my PC is 599F1D30. Now I need to sniff data passed to this function. There are several possible approaches. You can try using VisualStudio & Reflector plugin as SpoonStudio tried, you can try using ILSpy and it’s debugger plugin, or you can inject DLL into crackme process, as suggested by noth!ng – but I prefer to use OllyDbg. Load crackme in OllyDbg, make sure that all the anti-anti-debug plugins are working, all the exceptions ignored, put a breakpoint on 599F1D30 and hope for the best. Nope. Operators.CompareString is called literally thousands of times. So, we need to do something smarter. For example, we can use conditional logging breakpoints in Olly. Those breakpoints are quite slow, but it’s still faster than to write some sort of hooking DLL and inject it into crackme. So, we need to set 2 logging breakpoints – one for each string compared. Here is first one: Place second breakpoint at the next instruction (59CD1D31) and log string atedx+8. Run the crackme, enter some fake but easily recognizable serial and few minutes later we have the answer: My entered serial was “1234567890123456789012345678901234567890” and it’s being compared to “C49476D583364356253377056314435396D456F44796C7A55746431564433544″. Hmm, could that be the correct serial for my nickname? Yes, it is! Final notes This was quite nice crackme and I only showed the simplest way to beat it. When you start looking into it, you’ll find some nice anti-debug tricks, some nice anti-patching tricks and pretty nicely obfuscated code. But that’s a matter for another story. Have fun!
  41. 8 points
    Patching Java at runtime: Link: http://armoredbarista.blogspot.ro/2012/01/patching-java-at-runtime.html
  42. 8 points
    StrongName tools - source code C# This include: Assembly_Resigner Minimum_Resign_Calculator PKT_AssemblyRef_Replacer StrongName_Killer StrongNameVerifier Atached or: http://www.multiupload.nl/KF67L0KK1K StrongName.zip
  43. 8 points
    I disabled it... well the negative and positive rating. Some people I found are not mature enough to use the system as it was intended, I should have followed my initial instinct and never enabled it to begin with! However I have re-enabled the default board setting to the "Like" feature... Ted.
  44. 7 points
    Done! This has been added for your user group. I will see how this progresses. Obviously there is a possibility this could be abused by members however I currently trust persons in this group will use it appropriately. Done! You can now download PM's individually or bulk in HTML. The output HTML template is a bit crude. If you have some suggestions I'll contact the developer and propose the ideas with some of my own. Of the other suggestions proposed here I will reply to you all after I have thought them over and have appropriate time to reply accordingly. Thank you! Ted.
  45. 7 points
    But bp on strcmp, correct key will be in EAX register and stack.
  46. 7 points
    Unpacked file attached. Original filename is apuromafo_protected.exe. This string can be found in memory just around filename check, so no problem here. Finding OEP in new Enigma 5.50-5.60 is very easy. Data structure can be found in Enigma VM section like: <RVA of OEP> <size of PE header> 0x400000 // always, even if imagebase is different O_o <offset of second section> Fixing regular API and VM API is the same as in previous versions. OEP is not virtualized. I've also returned custom values from Enigma API and placed them in stack. Feel free to ask questions. apuromafo_protected_unpacked.zip
  47. 7 points
    To me there are a few factors that have gone into the community dying out: 1. Money - This is a major contributor. Before there wasn't many aspect to profiting off things on the internet, it was still a new / fresh idea and it was not really ever attempted. Payment models did not exist outside of using major credit card vendors so the ease of setting up methods to charge people for things was not around yet. (Stuff like Paypal etc.) Slowly, it became more and more known that you could easily charge people for your work (or in most cases any more others work). More and more people started either selling their stuff or stopped releasing things because it was being stolen and sold elsewhere. 2. Attitude / Egos - The community ages ago was a lot more friendly in terms of teaching people, sharing knowledge and overall being a welcoming place for newcomers. Anymore, though, it is now an ego fest showing off who can do what faster/better, bragging about what they can do over someone else, etc. The actual welcoming atmosphere has gone out the window. There are less and less tutorials posted, less and less actual information posted on various targets. Instead you see posts referring to outdated information / outdated versions of things that leave someone new to guess or "figure it out yourself". There is a major lack of patience with newcomers now too. Someone can ask a basic question that could easily be answered but instead people would rather just chew that person out or be a total ass to them. This entirely defeats the purpose of even having a site specific to teaching and tutorials. Why advertise as that if that is completely not how it is? Even if the question is stupid or basic to someone, many often forget they were once that new to reversing themselves and just instead jump to flaming that new comer (again going back to the ego issues). 3. Rippers - This goes alone with issue 1. Ripping / stealing has become a major problem. Before, things were released with nfo's, it was considered the scene's method of copyright in a way. They were treated like law and everyone abided by them as such. That is no longer the case at all and they are more or less seen as a useless junk file anymore. At most, people enjoy looking at the art in them still, but that's basically it. Most will never even open one anymore unless they feel the need to for a serial key or some other important information. Rippers also ruin the aspect of releasing tools and such open source. For example, something more or less recent would be ConfuserEx. It is a great example of a protection project for .NET related binaries. It is entirely open source and has been a pretty popular tool. The developers of it as well as Confuser (the original before hand) put tons of time and effort into it, and you have tons of people that clone the source code, rebrand it with a different name, add maybe 1-2 new features to it then sell it as if they did everything. It completely kills a developers motivation to share anything. The same has happened with the game hacking community / scene. It is completely dead now. Sites like CheatHappens started ripping work of a lot of teams that released things for free for everyone to enjoy, and slowly it killed the motivation of those teams to bother anymore. Since then a few web teams have surfaced that do nothing but try and profit on basic cheats anyone could make if they learned how to use Cheat Engine within a week. Along with the fact that a lot of those teams stalk sites like Cheat Engine that still offer lots of cheats for free, and those teams will rip options made by others and put them into their paid-for trainers.
  48. 7 points
    Hi. My DevirtualizeMe series continue with this entry. I have protected a simple file containing 18 keyboard initiated functions with different virtual machines using a full version of Themida 2.3.5.0 . The file does not have any extra protection as the idea of this challenge is to understand the virtual machines. Also non-virtual machine protection settings are kept to a minimum, meaning no antidebug, no API redirection etc. Basically only antidump is enabled on top of the virtual machines. All of the virtual machine code blocks are identical in sense of instructions. List of function initiators: q = FISH32 White w = FISH32 Red e = FISH32 Black r = TIGER32 White t = TIGER32 Red y = TIGER32 Black u = PUMA32 White i = PUMA32 Red o = PUMA32 Black a = SHARK32 White s = SHARK32 Red d = SHARK32 Black f = DOLPHIN32 White g = DOLPHIN32 Red h = DOLPHIN32 Black j = EAGLE32 White k = EAGLE32 Red l = EAGLE32 Black As said earlier, the idea is just to understand the differences between the virtual machines. Thus the identical code blocks. ~ HellSpider devirtualizeme_themida_2.3.5.0_hellspider.rar
  49. 7 points
    Hello everyone, For x64_dbg I had to create a pattern finder and mudlord asked me to extend it with a pattern search & replace ability. Example of usage: #include "patternfind.h"int main(int argc, char* argv[]){ unsigned char data[0x100]; memcpy(data, main, sizeof(data)); //find pattern offset size_t found = patternfind(data, sizeof(data), "68 ?? ?1 0? 00"); printf("found: main+%p\n", found); if(found==-1) //not found return 0; //print current data for(int i=0; i<5; i++) printf("%.2X ", data[found+i]); puts(""); //search & replace if(!patternsnr(data, sizeof(data), "68 ?? ?1 0? 00", "?? ?1 1? 21 23")) return 0; //search & replace failed //print replaced data for(int i=0; i<5; i++) printf("%.2X ", data[found+i]); puts(""); return 0;}Output:found: main+0000002668 00 01 00 0068 01 11 21 23Feel free to use it wherever you like, credit (link to http://x64dbg.com) is appreciated, but not required. Attached the full source (only ~150 lines) Greetings, Mr. eXoDia PatternFindUpdate.rar
  50. 7 points
    Hi guys, Just wanted to say Hi to all of you, I did not have much time these past two or three years. I am probably very outdated in reversing right now I am doing a PhD in the US, hopefully I will be done by the end of this year. I hope that there are members that still remember me I really miss the old days ;-( Special greetings to Teddy, quosego, metr0, UFO and the others. SC
  • Newsletter

    Want to keep up to date with all our latest news and information?
    Sign Up
×
×
  • Create New...