Notes on SendMessageRemote()
(03feb10) (SendMessageRemote() is a useful function for doing GetWindowText() on dialog items in another process. Due to implementation details GetWindowText() often fails if you try using it for that) (running windows vista 32-bit) the last parameter of david ching's SendMessageRemote() is the exact maximal number of bytes that his code will write to your buffer whose address you pass in the LPVOID fifth parameter e.g.since WM_GETTEXT writes wchar_t's you will get (assuming the window whose text is being read has a title that big) 8 and 1/2 wide-chars written to your memory and it will NOT write the terminating null note that WM_GETTEXT wParam msdn says is the maximal number of characters to transfer so dont you think that would limit SendMessageRemote() (indirectly) to only transfer 6.5 wide-chars to your buffer? (if you specify wParam==13) no. because WM_GETTEXT is 'smart' enough to know that wchar_t's are two bytes thus it thinks you told it 'my buffer is 26 bytes big' but microsoft has a bug! they say it returns the number of wide-chars written not counting terminating null. therefore you would expect in our example since in the remote process it thinks it had a 26 byte buffer it would write 12 wide chars and then a terminating null it should return 12 it actually returns 25 in my testing!* anyway the upshot is that you can just put 999 in the wParam to WM_GETTEXT and the 'real' restriction is what you tell SendMessageRemote() in the sixth size_t parameter you will be safe as long as you set that size_t to size of your buffer minus one (and do the terminating null yourself) [to test: what if the title of the window is 'Short' i.e. there are only ten bytes worth of wide char to send over? will david ching's code mindlessly write 10 bytes then perhaps 7 bytes of memory rubbish from the other injected process?] [it seems SendMessage() microsoft code processing WM_GETTEXT does some 'safe buffering' stuff where it takes the actual strlen() of the stuff in say an edit box and allocates separate string that has that text and null terminated] [then it gives THAT safe buffer to david ching's remote thread and that remote thread presumably hits terminating null and even though you request 17 bytes of raw memory transfer the remote thread is smart and only writes 12 bytes to your LPVOID the wchar_t's (S)(h)(o)(r)(t)(0)] [actually it will not write any terminating null perhaps it 'knows about' the strlen() being 5, scribbled down somewhere by WM_GETTEXT processing code] [point is if WM_GETTEXT sees wParam too short for the buffer it doesnt write terminating null to its own buffer, and somehow david ching remote thread is aware of this and also does not write a terminating null] [therefore again in that case when strlen() exactly equals wParam you will have to null terminate your LPVOID] [final note seems to be bug in ReadProcessMemory() used by david ching it says it wrote 17 bytes but i plainly see in my buffer it only wrote the (S)(h)(o)(r) (t) and left buffer slots after that untouched, didnt even copy garbage. this is with wParam set to 5 for WM_GETTEXT] *as you can see if you read on it actually DOES only write 26 bytes worth of wide chars. though it will write 13 wide chars and let you worry about terminating null. the real funny part is that i dont know if in the remote process since it scribbles somewhere '25' to return to you if it was dumb enough to write 25 wide chars to a buffer the user said 'size is 13' for Addendum: Boy things get really odd. If you set wParam==5 but have _six_ characters in the edit box 'Longer' and david ching size_t_L_param is 17 you only get 'Longe' back! And the remote thread SendMessage() returns 6! Whatever..