Log in

View Full Version : how to....make a buffer


jcsn
June 10th, 2003, 13:58
Ok, this should be the most confusing post ever..


Basically, I have a mail program which sends "HELO (your_host_name)" to the mail server, and I'm trying to get it to send "HELO (random_string)."

I was able to change it and make it send a static string like "HELO yahoo.com," but my main problem with having it send a random string is converting the integer to a string. To get the "random" number, I'm calling GetTickCount, which (I think) sets EAX to it's return value.

I've read the other posts on this board about converting integers to string by using _wsprintfA. That isn't available in my target, but I found sprintf which seems to be the same, so that's what I've been using instead. NOW! my problem (I think) is how I'm setting aside a buffer for sprintf to use. I tried opening the program in Hiew and finding a bunch of free space (bunch of 0's) and changing them to 20's for spaces, then passing the address of that for the buffer and it errors (well, freezes Olly). I also tried just pointing it to an address with a bunch of zero's and it errors, as it probably should.

I hope you understand what the hell I'm talking about.

Here's the sprintf changes I've made:

I changed (this is right after it gets "your_host_name" with gethostname, and the hostname is in EAX)
Quote:
00464CFE . E8 B5FCF9FF CALL advanced.004049B8

to
Quote:
00464CFE /E9 B94D0800 JMP advanced.004E9ABA


So this jumps to the extra sprintf code I'm putting in. Then..
Quote:

004E9ABA E8 6FCE9977 CALL KERNEL32.GetTickCount
004E9ABF 50 PUSH EAX ; GetTickCount return value?
004E9AC0 68 EE9A4E00 PUSH advanced.004E9AEE ; ASCII "%X"
004E9AC5 68 F19A4E00 PUSH advanced.004E9AF1 ; ASCII " " (there's more spaces, only shows one on messageboard)
004E9ACA E8 F0DCAA77 CALL ntdll.sprintf
004E9ACF A1 F19A4E00 MOV EAX,DWORD PTR DS:[4E9AF1] ; replace EAX, which has "my_host_name" with the GetTickCount output
004E9AD4 E8 DFAEF1FF CALL advanced.004049B8
004E9AD9 ^ E9 25B2F7FF JMP advanced.00464D03


Is this at all salvagable, or is it completely wrong? I know for sure it's at least a little bit wrong hehe

Lunar_Dust
June 10th, 2003, 14:12
Just a question -

Did you look at the memory area and make sure the string was there right after the call to sprintf? If that works, then at least you know your code snippet is doing its job, and the problem lies elsewhere (like, for example, it may expect a unicode string)

-Lunar

jcsn
June 10th, 2003, 14:17
Hmm...I saw the string in one of the registers I think. I've changed it around so many times I don't remember when. I'll go look now 8u)

Thanks for quick reply


Edit:

Ok, I think when I saw the string in one of the registers it was when I was using an alternate method I saw posted on here, which used a loop. I just tried:

Quote:

004E9ABA E8 6FCE9977 CALL KERNEL32.GetTickCount
004E9ABF 50 PUSH EAX
004E9AC0 68 EE9A4E00 PUSH advanced.004E9AEE ; ASCII "%X"
004E9AC5 68 F19A4E00 PUSH advanced.004E9AF1 ; ASCII " "
004E9ACA E8 F0DCAA77 CALL ntdll.sprintf
004E9ACF A1 F19A4E00 MOV EAX,DWORD PTR DS:[4E9AF1]
004E9AD4 E8 DFAEF1FF CALL advanced.004049B8
004E9AD9 ^ E9 25B2F7FF JMP advanced.00464D03


I set a breakpoint on 004E9ACF and it never got there, so I assume the call to sprintf is erroring and the program's catching it.

Edit2: And I set a breakpoint on 004E9ABA just to make sure my code was being run. (it is)

diz
June 10th, 2003, 14:23
Quote:
Originally posted by jcsn
program in Hiew and finding a bunch of free space (bunch of 0's) and changing them to 20's for spaces, then passing the


don't change to 20h, leave 00h's there

Quote:

004E9ACF A1 F19A4E00 MOV EAX,DWORD PTR DS:[4E9AF1]


maybe "mov eax, offset 4E9AF1"? If eax oryginally had host name then it was a pointer to the string. You want to make it a pointer too.

jcsn
June 10th, 2003, 14:31
Ok, I changed them back to 00's and I get the same problem. Olly says it's running, but the target program's frozen and the code after the sprintf call doesn't get executed. Be nice if it gave me some sort of error 8-T

Edit: This brings me to another question. To find buffer space, I'm just scrolling around in Olly looking for a bunch of 00's. Is the entire file fair game or is there only certain places you can put a buffer?

diz
June 10th, 2003, 15:14
If it's data section then you should not take this space because it can be used by program. Better make a new section and place data there.

I just compiled some program in vc++ with sprintf function and actually this whole function was hardcoded in this exe. In your's snippet I see that it's imported from ntdll, hm... I'm confused

The best way would be IMO for you to write your own proc which will convert dword to string. If you don't know how, you can go here http://m4sh.atpa.eu.org/~bart/asmpak.php3 (hi bart ) and try asmpack. The descriptions are in polish but you should be able to work it out.

jcsn
June 10th, 2003, 15:29
Alright, thanks. So maybe I should use Snippet Creator with bart_dword2hexstr.inc? I'll see how that works out.

Thanks fellas

jcsn
June 10th, 2003, 16:27
One more question.

Quote:
If it's data section then you should not take this space because it can be used by program.


Would the CODE section be ok or should I just make a new section no matter what? I ask because I'm not sure how to make a new section and would have to find out first. 8-p

Edit: To clarify, I'm asking if it's ok to put extra code in some free space in the code section.

diz
June 10th, 2003, 16:43
Quote:
Originally posted by jcsn
One more question.
dit: To clarify, I'm asking if it's ok to put extra code in some free space in the code section.


yes, if there are 00's than it's ok to use it but you need to put variables somewhere. They can't be placed in code section unless you change it's characteristics to allow writing to it (the code section is only readable by default). Use any PE editor (ProcDump, LordPE or PEEditor) to do it. U can use them to add new section, too.

Or use CodeSnipperCreator, select appropriate option and it will create new section with your own code automagiclly

squidge
June 10th, 2003, 16:54
Way I normally do it is this:

Load executable into PE editor (eg. LordPE). Get the raw size of the section, load the hex editor, and go from the end backwards and try and squeeze you code in there. Try and keep your code on a 16 byte align (use LordPE to convert the file offset to VA, and make sure last hex char is 0 - so for example 401990 is aligned ok).

Or.... (bit more complex)

View sections. Looks at RawSize/VirtualSize.

If raw size is smaller than virtual size, then subtract them, and you have at least this many bytes to play with Add your required number of bytes to rawsize, and realign the file. After realigning, you have space to play with.

Or...

Add a new section.

BTW, I hope this is a learning exercise, as you do know your ISP will completely ignore anything you put after the HELO command apart from placing into remarks of mail bounces, etc? For tracing purposes, your ISP itself will add an extra header to each of your emails with your IP address (sometimes encoded). So by giving HELO a random number instead of your host name doesn't really accomplish anything.

jcsn
June 10th, 2003, 17:00
Quote:
So by giving HELO a random number instead of your host name doesn't really accomplish anything.


Heh, yeah. The person who wants me to change it just doesn't want their host name showing up in the helo part of the header for some reason. 8-T

I didn't know about that aligning thing (add that to the huge pile of stuff I don't know)...I'll change mine so it's aligned properly.

Thanks fellas

dELTA
June 10th, 2003, 18:18
It seems to me like your solution is very overkill just in general, and it's getting worse by the minute, so I feel urged to intervene here before it goes completely out of hand.

First of all, why not just send a hardcoded bogus string after the HELO if all you want to do is to prevent the original string from being sent? Why the random integer?

Second of all, if you necessarily want to write a random integer string, you don't even have to write a generic integer to string function, just do it with some simple inline code like:

mov [string_char], (rand_int mod 10) + 48

(repeat for each digit you want)


dELTA

PS.
Yes, that is pseudo-code, but you get the picture.

jcsn
June 10th, 2003, 18:38
Quote:
First of all, why not just send a hardcoded bogus string after the HELO if all you want to do is to prevent the original string from being sent? Why the random integer?

Quick answer: my friend asked "Could you make it do HELO (rand) instead of HELO blah?" lol


Quote:
mov [string_char], (rand_int mod 10) + 48


Thanks, gave me the genius idea of just using the last number from GetTickCount, since that's random enough, hehe.

doug
June 11th, 2003, 14:07
just one comment..
I thought that, due to its variable number of parameters, the sprintf function was part of another calling convention (_cdel i believe), where the caller has to fix the stack.
That's the case in C & for the win32 wsprintf. Therefore, you would have to add 12 to esp (if you pushed 3 dwords) after calling sprintf. It might not always be noticed, but not fixing esp for these functions is definately going to cause your problems at some point.

Btw, the free space you found in the exe (for your buffer).. that wasn't in any code section, right?

Also, if you are careful with what you are doing, you can place your buffer on the stack.
Substract esp to make space & call sprintf, do everything with u need with your buffer, add to esp to shrink it (and clear the buffer).

--
doug