|
Hi, the problem is that the bytes what i get logged are disordered and not in proper row and somehow they are even splited.
I used apimonitorig software and monitored readprocessmemory and sawed that it holds byte rows for sure this was the output from apimonitorig software : lpBuffer 0x014D0020: {4D 5A 90 00 03 00 00 00 04 00 00 00
This is my hooked readprocessmemory where i am trying to log the lpBuffer what is holding byte rows.
BOOL (__stdcall* pReadProcessMemory)(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead);
BOOL __stdcall hookedReadProcessMemory(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead)
{
bool returning = pReadProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead);
char* mybytes = (char*)lpBuffer;
for (int i = 0; i < nSize; i++)
Log( "lpBuffer: %x \n", mybytes[i]);
return returning;
}
And the log output is like this:
lpBuffer: 4d
lpBuffer: 5a
lpBuffer: ffffff90
lpBuffer: 0
lpBuffer: 3
lpBuffer: 0
lpBuffer: 0
lpBuffer: 0
lpBuffer: 4
lpBuffer: 0
lpBuffer: 0
lpBuffer: 0
lpBuffer: ffffffff
lpBuffer: ffffffff
lpBuffer: 0
lpBuffer: 0
lpBuffer: ffffffb8
Please help what i am doing wrong im out of ideas
|
|
|
|
|
nah1337 wrote:
char* mybytes = (char*)lpBuffer;
Change it to :
unsigned char* mybytes = (unsigned char*)lpBuffer;
Just say 'NO' to evaluated arguments for diadic functions! Ash
|
|
|
|
|
Hi, it did not make any difference the log is still same:
Here is the output
lpBuffer: 4d
lpBuffer: 5a
lpBuffer: 90
lpBuffer: 0
lpBuffer: 3
lpBuffer: 0
lpBuffer: 0
lpBuffer: 0
lpBuffer: 4
lpBuffer: 0
lpBuffer: 0
lpBuffer: 0
|
|
|
|
|
I'm sorry but I don't see what is wrong with this ouptut; it is the same sequence of bytes shown in your orignal message as received in your memory buffer.
Just say 'NO' to evaluated arguments for diadic functions! Ash
|
|
|
|
|
I wanted to log them straight out i mean like in row not as separated like my log functions does it, but if that is impossible then its ok for me.
|
|
|
|
|
nah1337 wrote: wanted to log them straight out i mean like in row
Well, it's just a matter of correcting your code so that you do not log each item on a separate line.
Just say 'NO' to evaluated arguments for diadic functions! Ash
|
|
|
|
|
Hi to everybody,
I am creating a native win32 dll with the following function.
LPCWSTR __stdcall DisplayInfo()
{
wchar_t* hello =_T("Yahoooooooooo!");
return (LPWSTR)hello;
}
Program compiles successfully. But when i use it in my visual basic application, the entire IDE crashes.
Private Declare Function DisplayInfo Lib "dllexample1" () As String
Private Sub Command1_Click()
MsgBox DisplayInfo
End Sub
Help?????
:: Roses ::
|
|
|
|
|
I'm no expert, but I do not think you can call a C++ function directly like this, and expect a String to be returned. I would suggest posting your question in the Visual Basic forum, as someone there will probably know the answer.
Just say 'NO' to evaluated arguments for diadic functions! Ash
|
|
|
|
|
The hello string is a local variable within the DisplayInfo() function; so when you return, the memory is freed. You return a pointer to the string, but the string's memory got overwritten.
To fix this this particular problem, you could make hello a static variable; this will keep its address valid after returning.
Another, more generally usable way would be to pass a string variable to DisplayInfo() and copy hello 's content to it inside the function.
modified 13-Sep-18 21:01pm.
|
|
|
|
|
Actually, in this particular case, the local variable points to a string literal that is, of course, not freed.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
I wouldn't be too sure about that. The variable hello is not declared const, so it would be valid to modify the content of this string later in the code like this:
hello[3]=0;
This means the compiler does have to create a local string variable on the stack, inside this function. And this particular string variable will indeed be destroyed upon return.
You might argue that there is no such modification, but since the function itself passes a (non-const) pointer to this string, the caller might modify the contents instead! Also, later calls to that function need to initialize hello with the original string, not an address to a presumed literal which in the meantime might have been changed to god knows what. So what you'll want to pass is a copy of the literal being used for intialization, not the address of the literal itself!
|
|
|
|
|
Stefan63 wrote: This means the compiler does have to create a local string variable on the stack, inside this function. And this particular string variable will indeed be destroyed upon return.
You are wrong, at least on Microsoft compiler, these strings have static storage duration, see http://msdn.microsoft.com/en-us/library/0h227906.aspx[^].
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Duh
Microsoft wrote: Microsoft Specific
You win
P.S.:
if a DLL uses a static variable, and gets called just once, will the variable be released after the last (and only) call, or at the end of the lifetime of the application that calls it?
I'm pretty sure about a C++ app calling a C++ DLL; but not so much about another language app that might use other DLL bindings...
|
|
|
|
|
Actually it looks a more general fact, see, for instance http://stackoverflow.com/questions/267114/scope-of-string-literals[^] (look at reported sentences of the C++ standard).
Static variables are, ehm, static, in other words, must be there...
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Thanks for the link. My problem with the original question was that I didn't notice the 'C' part of the return type, assuming it was LPWSTR, like the cast on the return statement. Also the variable hello is not a const string pointer. At the very least the local variable used to temporarily store a pointer to the literal is a non-const pointer however, and thus should be usable for modifying the string it points to!
I've tested it in Visual Studio though, and it appears that even a non-const string pointer initialized to point to a string literal may not be used to change that literal: code that tries to do this does compile without warnings, but when run causes a run-time exception. For all I know this behaviour is Microsoft Specific.
Consider this example
char* DisplayInfo()
{
char* hello = "hello!";
return hello;
}
int _tmain(int argc, _TCHAR* argv[])
{
char* h = DisplayInfo();
if (strlen(h)>0)
h[0] = 0;
return 0;
}
When you call DisplayInfo, normally all you should care about is the function prototype, which states it returns a pointer to characters. By testing the string length you assert that the pointer is non-zero and points to an array of characters of non-zero length. it should be totally legitimate to alter individual characters within that array, as the return type was non-const.
But it turns out doing so might result in a run-time error, depending on how DisplayInfo is being implemented, and based on how string literals are being treated, even when dealing with non-const string types!
The link you provided mentions const string types only, and thus doesn't apply here - this is indeed compiler-specific, and might indeed just be Microsoft Specific.
Regarding my PS question: I was just being overly cautious. A dynamic library will only be loaded once it's used, not neccessarily upon starting the application that uses it. So the static variables will not exist from the start. I wondered whether for similar reasons the DLLs might be discarded once they are no longer needed. But of course, that is absurd, as the application wouldn't know in advance when a DLL is being called for the last time...
P.S. (another one):
I just noticed that the last section of the quote from the standard states
The C++ Standard wrote: The effect of attempting to modify a string literal is undefined.
This implies you do in fact have a non-const string pointer. Before it says
The C++ Standard wrote: An ordinary string literal has type "array of n const char" (or const wchar_t).
How can you modify const char? I am confused now
modified on Monday, January 10, 2011 8:52 AM
|
|
|
|
|
It looks like VB6 , isn't it?
As far as I know the Visual Basic Runtime takes for granted that DLL s' functions use ANSI strings and takes care about the conversions, hence you have to use char* instead of wchar_t* inside your DisplayInfo function.
BTW have a look, for instance, at the following tutorial http://www.programmers-corner.com/tutorial/4[^].
[update]
Please note you mustn't return the string that way, you should instead modify the passed buffer, see this MSDN article[^].
[/update]
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
modified on Sunday, January 2, 2011 12:33 PM
|
|
|
|
|
As far as I know, the VB6 strings are unicode and their VC correspondant is the BSTR type...
|
|
|
|
|
Sauro Viti wrote: As far as I know, the VB6 strings are unicode
Yes, that's the reason I was talking about 'conversion'.
Sauro Viti wrote: and their VC correspondant is the BSTR type...
That holds for VB6 interacting with C++ COM components, however for standard C++ DLL s the scenario is a bit different (according to MSDN[^]):
In order to develop your C DLL, it is important to know how Visual Basic handles strings internally in order to know how they will be passed to your DLL functions. Most C functions expect a string to be a null-terminated, ASCII character array. But Visual Basic uses a type-safe Automation string called a BSTR. For the Win32 platform, a BSTR is a long pointer to an allocated memory structure containing a Unicode character string and a 32- bit integer prefix that stores the length of the string.
You can ignored most of this difference, because Visual Basic will automatically convert any Unicode BSTRs to ASCII before passing them to an external function.
BTW: Note the typo in 'ignored'...
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
CPallini wrote: You can ignored most of this difference, because Visual Basic will automatically convert any Unicode BSTRs to ASCII before passing them to an external function.
This will mean that VB pass strings to DLLs as ANSI, but what's about the opposite: what VB does with strings returned by a DLL function call?
|
|
|
|
|
Of course VB6 takes care of performing the opposite conversion (you know, that language was highly engineered... ).
However that doesn't happen on the function return value but on passed parameter (I need to update the reply to the OP).
From the same MSDN article (did you read it?):
void __stdcall FillString(LPSTR pszString, LONG cSize)
{
char buffer[] = "Hello from the C DLL!";
if (cSize > strlen(buffer))
strcpy(pszString, buffer);
}
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
thanx. but if i want to change this function for unicode what changes have to be done, so this function supports unicode.
gold
|
|
|
|
|
I suppose you should make a COM component.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
The problem you try to solve is passing a string to a caller, where the caller has no knowledge of the length of that string, and therefore cannot easily provide a buffer variable to store that string into.
The posted solution does not work, because the compiler will create a local copy of the string literal you used for initialization, and the address to that copy will be invalidated upon return.
If you used const wchar_t* instead of wchar_t* , and the appropriate const string types, it might have worked. But if you want a non-const string, then there are really only two possible ways to deal with this:
1. use a secondary function that enables the caller to inquire about the expected length of the string, and then pass a buffer of sufficient size to DisplayInfo.
const wchar_t* HELLO = _T("Yahoooooo");
int DisplayInfoSize()
{
return wcslen(HELLO);
}
LPCWSTR __stdcall DisplayInfo(wchar_t* hello)
{
return wcscpy(hello, HELLO);
}
2. Have DisplayInfo allocate memory on the heap to story that string.
const wchar_t* HELLO = _T("Yahoooooo");
LPCWSTR __stdcall DisplayInfo()
{
wchar_t* hello = new wchar_t*[wcslen(HELLO)+1];
return wcscpy(hello, HELLO);
}
Solution 1 is awkward, but it makes sure the caller can release the allocated memory once the string is no longer needed. Solution 2 might create a memory leak, if the caller has no way to properly release the string being passed to it (which may very well be the case if it's called from VB), but it would not require a change of the interface.
P.S.:
Just realized that the return type on your DisplayInfo function is a const string! This means that the compiler should indeed just return a pointer to the literal as others already pointed out. I'm sorry, I got confused by the cast in your return statement (which is non-const string!)
The suggestions above might still work if none of the other responses are helping.
modified on Monday, January 10, 2011 6:34 AM
|
|
|
|
|
hello guys... When I craete a NEW solution in VS 2008 and choose the solution combo box as "Add to the Solution", only then I can add a reference (a dll reference). But If I create a solution and choose the solution combo box as "Create New SOlution", it does not show me the required reference even after providing all the necessary paths. How can I add the reference when I choose the "Create a New Solution"??
|
|
|
|
|
I want to ask you something ( maybe ) simple question :
Can I initialize an CListBox& ListCtrl reference with null value ? Because later , I want to use ListCtrl reference variable in many if contitions ...
I try :
CListBox& ListCtrl = NULL;
and doesn't go ...
Give me an error like this :
initializing' : cannot convert from 'const int' to 'class CListBox &'
|
|
|
|
|