News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

BEAEngine

Started by FlySky, November 30, 2011, 06:25:05 PM

Previous topic - Next topic

donkey

Quote from: FlySky on December 11, 2011, 08:24:47 AM
Edgar,
First of all thanks for all your help.
I tried what you suggested. The Assemble function still returns: 80004005 which is the E_FAIL return code.
Could it be the created string causing the error?.



Yes, it could be, MultibyteToWidechar will create a UNICODE not an ANSI string.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

FlySky

It's indeed the string donkey. Infact it seems you have to give the assemble function a NULL terminated string.
The string I created is filled by using the lstrcat function and therefor doesn't has a NULL terminator?.
I created the following string definition in the data section

TestString         DB 'mov esi, [esp+4b0]',0  //Test string

Now running the assemble function it allocates the buffer at 51D8000
than it fills it with the opcode bytes. Looking it up in the debugger:
051d8000 8bb424b0040000  mov     esi,dword ptr [esp+4B0h] //perfectly translated.

So my problem is not having a NULL terminated string.
Is it possible to add the NULL terminator after a string is created with lstrcat for example?




donkey

Glad you got it working FlySky, yes, PCSTR is always a pointer to a NULL terminated string (Pointer to C STRing). The lstrcat function will always NULL terminate the resulting string unless there is an error so it's not likely that API was the issue. You should look through your code to find the actual cause however, since you might want to change the function later it could be important to know what was changed to get it working to prevent introducing the same bug in future versions.

Edgar
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

FlySky

I am atm testing what's causing the error, it has to do with the string building. So I am testing a couple of instructions which I append using lstrcat.
I will post my findings and final solution when I figure it out.
Close to finishing this part. Thanks for all the input.

FlySky

I've fixed the error.

It has indeed to do with the way the string is being generated.

I used htodw function to convert an hexadecimal string into it's dword form.

so ESP + 4B0 was translated as ESP + 000004B0.

And this is exactly what the assemble function from the IdebugClient does not like.
It doesn't recognize all the 00000 before 4B0.
So I had to cut the zero's off and I am using the following function to assemble strings:

invoke Assemble, offset AssemblyResult, offset FullRebuildPattern1 // Call assemble function.

AssemblyResult is pointer to a buffer where opcodes are stored.
FullRebuildPattern1 is pointer to a buffer which holds the string to rebuild. In my case it holds: mov esi, [esp+4B0]

Assemble FRAME pTarget, pInstr
   uses Ebx
//   LOCAL status:%UINT_PTR
   LOCAL EndOffset:Q
   LOCAL pBuffer:%UINT_PTR
//   LOCAL DisassemblySize:%UINT_PTR
   LOCAL wfmt[MAX_PATH] :W
   
   invoke CoTaskMemAlloc,1024
   mov [pBuffer], Rax
   
   invoke DebugCreate,offset IID_IDebugClient, offset pIDebugClient
   test Eax, Eax
   jnz >>.DBGCFAIL
   CoInvoke(pIDebugClient,IDebugClient.QueryInterface,offset IID_IDebugControl,offset pIDebugControl)
   test Eax, Eax
   jnz >>.QIFAIL

   invoke GetCurrentProcessId
   CoInvoke(pIDebugClient,IDebugClient.AttachProcess,0,0,eax,DEBUG_ATTACH_NONINVASIVE | DEBUG_ATTACH_NONINVASIVE_NO_SUSPEND)
   test Eax, Eax
   jnz >>.ATTACHFAIL
   CoInvoke(pIDebugControl,IDebugControl.WaitForEvent,DEBUG_WAIT_DEFAULT,INFINITE)

   :
//   invoke MultiByteToWideChar,CP_ACP,NULL,[pInstr],-1,[pBuffer],MAX_PATH  //convert to ansi string
//   invoke WideCharToMultiByte,CP_ACP, NULL, [pInstr],
   
   mov Ebx, [pInstr] //holds instruction to convert
   mov Edx, [pTarget] //holds place to store the recreated instruction
   
   CoInvoke(pIDebugControl,IDebugControl.Assemble,Edx, 0, Ebx, offset EndOffset,0)
      
   test Eax, Eax
   jnz >>.DISASMFAIL

   CoInvoke(pIDebugControl,IDebugControl.Release)
   CoInvoke(pIDebugClient,IDebugClient.Release)
   invoke CoTaskMemFree,[pBuffer]
   ret

   .DBGCFAIL
   invoke FormatMessage,FORMAT_MESSAGE_FROM_SYSTEM,NULL,rax,NULL,[pBuffer],1024,NULL
   invoke MessageBox,NULL,[pBuffer],"DebugCreate failed",0
   ret
   .QIFAIL
   invoke FormatMessage,FORMAT_MESSAGE_FROM_SYSTEM,NULL,rax,NULL,[pBuffer],1024,NULL
   invoke MessageBox,NULL,[pBuffer],"QueryInterface failed",0
   CoInvoke(pIDebugClient,IDebugClient.Release)
   ret
   .ATTACHFAIL
   invoke FormatMessage,FORMAT_MESSAGE_FROM_SYSTEM,NULL,rax,NULL,[pBuffer],1024,NULL
   invoke MessageBox,NULL,[pBuffer],"Attach to process failed",0
   CoInvoke(pIDebugControl,IDebugControl.Release)
   CoInvoke(pIDebugClient,IDebugClient.Release)
   ret
   .DISASMFAIL
   invoke FormatMessage,FORMAT_MESSAGE_FROM_SYSTEM,NULL,rax,NULL,[pBuffer],1024,NULL
   invoke MessageBox,0,[pBuffer],"Disassemble failed",0
   CoInvoke(pIDebugControl,IDebugControl.Release)
   CoInvoke(pIDebugClient,IDebugClient.Release)
   ret
EndF

Thanks for all the input everyone. I hope this solution is helpfull to anyone.


donkey

Hi FlySky,

Since you are not using pBuffer there is no need to allocate it with CoTaskMemAlloc or to free it with CoTaskMemFree. You should remove the calls.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable