0xNOP Posted January 31, 2016 Posted January 31, 2016 (edited) I'm using a library called PE Bliss it's a PE Manipulation library, pretty good, however, I'm having problems writing data to a PE section this is my section scope so far: ////////////////////ADD NEW SECTION////////////////////// section new_section; cout << "[+] Adding New Section ..." << endl; //Section Name (8 Chars MAX!) const char section_name[8] = ".hw"; char data[] = { 0x6A, 0x00, // push 0 0x68, 0x00, 0xA0, 0x02, 0xE1, // push "PeBliss" 0x68, 0x00, 0x00, 0x00, 0x00, // push "Built with PeBliss" 0x6A, 0x00, // push 0 0xE8, 0x00, 0x00, 0x00, 0x00, // call MessageBoxA 0xE9, 0x00, 0x00, 0x00, 0x00, // JMP to OEP 'B','u','i','l','t',' ', // Data String... 'w','i','t','h',' ', // ... 'P','e','B','l','i', 's', 's' }; // ... // New Section Name (our Hello World section :D) new_section.set_name(section_name); // Set New Section Permissios as R/E/W new_section.readable(true).executable(true).writeable(true); // Setting New Section Size image.set_section_virtual_size(new_section, 200); cout << "[+] Injecting Data to PE ..." << endl; UINT32 rawDataOffset = new_section.get_pointer_to_raw_data(); *(UINT32*)(&data[3]) = image.rva_from_section_offset(new_section, 35); *(UINT32*)(&data[8]) = image.rva_from_section_offset(new_section, 24); UINT32 *pointer = (UINT32*)&MessageBoxA; cout << "MessageBox Address: " << pointer << endl; *(UINT32*)&data[15] = *(UINT32*)&pointer; ///////////////////////////////////////////////////////////////////////////////////// // http://stackoverflow.com/questions/8510239/0x00-and-char-arrays/8510323#8510323 // ///////////////////////////////////////////////////////////////////////////////////// // As we write the stuff to the section, if the writter see it's null terminated 0x00, // There was a "bug" where it wouldn't write all the way and it would just stop, // thus assuming our Push 0 = "0x6A, 0x00" <- was null-terminated. string vData(data, data + sizeof(data) / sizeof(data[0])); /////////////////////////////////////////////////////////// // Write data to our image new_section.set_raw_data(vData); //Update everything. image.update_image_size(); // This has to be called before adding a new section. image.prepare_section(new_section); // Finally Adding our Section. image.add_section(new_section); cout << "[+] New Section Added to the Image!" << endl; It's all good up until I start writing the raw data into the section. what I want to do is to get the address of MessageBoxA and then write it where it should go, which is in the call defined in the char data[] you see above... My problem is that whenever I execute the: "cout << "MessageBox Address: " << pointer << endl;" it outputs the correct address of MessageBoxA onto the console, which is the value I should be expected to be written in the section now the thing is that when I load the executable any debugger, the address that got written is totally different from the one that it was showing me earlier... it's basically something like this: call <weird address> that weird address is nothing more and nothing less than (address where the call starts in assembly) 0014D013 E8 00 00 00 00 00 <- Example Plus the address of the MessageBoxA let's say 0074B657F so, in fact I get the correct value, but it gets added with the address of where the call starts... I hope I explained myself here, so ultimately it will end up like this: 004D013 + 0074B657F = the address that will be written in the raw data... so I know it's kinda confusing, but that is what is actually happening to me... ultimately I would like to write just the address of MessageBoxA into the raw data instead of doing that weird sum and using that result as address to write into the raw data... Note: this portion of the code is part of an actual project I'm working on: https://github.com/AxDSan/File-Infector Edited January 31, 2016 by 0xNOP
mrexodia Posted January 31, 2016 Posted January 31, 2016 I don't exactly get why you are using the address of MessageBoxA (which is probably a pointer to a JMP forwarder function) of the injector rather than the injected program. And yes, call destinations are relative (like your entire code should be). I always think of it as dw = start - addr - 5. The dw is the DWORD you put after the E8. I'd recommend you make your code relocatable: call @afterString "this is a string" @afterString: ; you have now effectively pushed the address of "this is a string" without having to worry about constants. @getImageBase: call @next @next: pop eax sub eax, XXXXX ; XXXX should be the final RVA of @getImageBase Now work with call @getImageBase ; imagebase will be in eax add eax, XXX ; rva of MessageBoxA import table address in injectee (get with PE library) push eax Check out the Multimate Assembler library I wrote an article on (as part of a deal with RaMMicHaeL to release Multimate Assembler as a library): http://rammichael.com/multiline-ultimate-assembler-library 1
0xNOP Posted January 31, 2016 Author Posted January 31, 2016 9 hours ago, Mr. eXoDia said: I don't exactly get why you are using the address of MessageBoxA (which is probably a pointer to a JMP forwarder function) of the injector rather than the injected program. And yes, call destinations are relative (like your entire code should be). I always think of it as dw = start - addr - 5. The dw is the DWORD you put after the E8. I'd recommend you make your code relocatable: call @afterString "this is a string" @afterString: ; you have now effectively pushed the address of "this is a string" without having to worry about constants. @getImageBase: call @next @next: pop eax sub eax, XXXXX ; XXXX should be the final RVA of @getImageBase Now work with call @getImageBase ; imagebase will be in eax add eax, XXX ; rva of MessageBoxA import table address in injectee (get with PE library) push eax Check out the Multimate Assembler library I wrote an article on (as part of a deal with RaMMicHaeL to release Multimate Assembler as a library): http://rammichael.com/multiline-ultimate-assembler-library pretty cool thanks for the input eXoDia
simple Posted January 31, 2016 Posted January 31, 2016 1. Adding new sections -will- trigger AV's. Don't add a new section if you can use existing 0x00 bytes, which most binaries have. 2. u have to assume the target binary will not have the address of MessageBox(). read about how shellcodes dynamically get addresses of functions w/out relying on import tables. exploit-db has a lot of examples, this is 1 of many - https://www.exploit-db.com/exploits/28996/ . 3. WinAPI already does everything pebliss does - there's a million code samples to use. 1
0xNOP Posted January 31, 2016 Author Posted January 31, 2016 22 minutes ago, simple said: 1. Adding new sections -will- trigger AV's. Don't add a new section if you can use existing 0x00 bytes, which most binaries have. 2. u have to assume the target binary will not have the address of MessageBox(). read about how shellcodes dynamically get addresses of functions w/out relying on import tables. exploit-db has a lot of examples, this is 1 of many - https://www.exploit-db.com/exploits/28996/ . 3. WinAPI already does everything pebliss does - there's a million code samples to use. awesome, thanks for this information!
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now