那然后比如我想调用里面的"speak".
怎么算接口表里函数的偏移?
下面是用eXeScope打开这个DLL的部分内容
Interface ISpVoice; // ISpVoice Interface
GUID={6C44DF74-72B9-4992-A1EC-EF996E0422D4};
function SetOutput(pUnkOutput:IUnknown; fAllowFormatChanges:I4): HResult;
function GetOutputObjectToken(out ppObjectToken:^^ISpObjectToken): HResult;
function GetOutputStream(out ppStream:^^ISpStreamFormat): HResult;
function Pause: HResult;
function Resume: HResult;
function SetVoice(pToken:^ISpObjectToken): HResult;
function GetVoice(out ppToken:^^ISpObjectToken): HResult;
function Speak(pwcs:LPWSTR; dwFlags:UI4; out pulStreamNumber:^UI4): HResult;
function SpeakStream(pStream:^IStream; dwFlags:UI4; out pulStreamNumber:^UI4): HResult;
function GetStatus(out pStatus:^SPVOICESTATUS; out ppszLastBookmark:^LPWSTR): HResult;
function Skip(pItemType:LPWSTR; lNumItems:I4; out pulNumSkipped:^UI4): HResult;
function SetPriority(ePriority:SPVPRIORITY): HResult;
function GetPriority(out pePriority:^SPVPRIORITY): HResult;
function SetAlertBoundary(eBoundary:SPEVENTENUM): HResult;
function GetAlertBoundary(out peBoundary:^SPEVENTENUM): HResult;
function SetRate(RateAdjust:I4): HResult;
function GetRate(out pRateAdjust:^I4): HResult;
function SetVolume(usVolume:UI2): HResult;
function GetVolume(out pusVolume:^UI2): HResult;
function WaitUntilDone(msTimeout:UI4): HResult;
function SetSyncSpeakTimeout(msTimeout:UI4): HResult;
function GetSyncSpeakTimeout(out pmsTimeout:^UI4): HResult;
function SpeakCompleteEvent: ^void;
function IsUISupported(pszTypeOfUI:^UI2; pvExtraData:^void; cbExtraData:UI4; out pfSupported:^I4): HResult;
function DisplayUI(hWndParent:wireHWND; pszTitle:^UI2; pszTypeOfUI:^UI2; pvExtraData:^void; cbExtraData:UI4): HResult;
12 个解决方案
#1
接口都获得了,直接->Speak就可以了
#2
那用汇编呢,假如EAX是接口的地址,先把Speak的参数PUSH进栈,再CALL DWORD (EAX + 偏移),好像这个偏移是50H,但我自己算不对,哪位大侠来简单再说一说呀,怎么算的!
#3
不懂也
#4
牛啊
#5
怎么没人来帮助我这个菜鸟??
#6
接口指向的地址才是函数地址开始的地方,也就是[EAX]+偏移 才是函数
#7
这是在网上看的别人的例子,编译成功,但不知那个偏移50咋来的!我本愚钝!
.586
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
include ole32.inc
includelib kernel32.lib
includelib ole32.lib
.data
CLSID_SpVoice GUID <096749377h, 03391h, 011D2h, <09Eh, 0E3h, 000h, 0C0h, 04Fh, 079h, 073h, 096h>>
IID_ISpVoice GUID <06C44DF74h, 072B9h, 04992h, <0A1h, 0ECh, 0EFh, 099h, 06Eh, 004h, 022h, 0D4h>>
TEXT db 'I',0,' ',0 ,'L',0 ,'o',0 ,'v',0 ,'e',0 ,' ',0 ,'Y',0 ,'o',0 ,'u',0 ,'!',0,0
.data?
PCOM dd ?
.code
; ---------------------------------------------------------------------------
start:
invoke CoInitialize,0
invoke CoCreateInstance,offset CLSID_SpVoice, 0, CLSCTX_INPROC_SERVER, offset IID_ISpVoice,offset PCOM
.if eax == 0
push 0
push 0
push offset TEXT
mov eax,PCOM
push eax
mov eax,[eax]
call DWORD PTR[eax+50h] ;PCOM->Speak(L"I LOVE YOU!", 0, 0);
.endif
invoke ExitProcess,eax
end start
.586
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
include ole32.inc
includelib kernel32.lib
includelib ole32.lib
.data
CLSID_SpVoice GUID <096749377h, 03391h, 011D2h, <09Eh, 0E3h, 000h, 0C0h, 04Fh, 079h, 073h, 096h>>
IID_ISpVoice GUID <06C44DF74h, 072B9h, 04992h, <0A1h, 0ECh, 0EFh, 099h, 06Eh, 004h, 022h, 0D4h>>
TEXT db 'I',0,' ',0 ,'L',0 ,'o',0 ,'v',0 ,'e',0 ,' ',0 ,'Y',0 ,'o',0 ,'u',0 ,'!',0,0
.data?
PCOM dd ?
.code
; ---------------------------------------------------------------------------
start:
invoke CoInitialize,0
invoke CoCreateInstance,offset CLSID_SpVoice, 0, CLSCTX_INPROC_SERVER, offset IID_ISpVoice,offset PCOM
.if eax == 0
push 0
push 0
push offset TEXT
mov eax,PCOM
push eax
mov eax,[eax]
call DWORD PTR[eax+50h] ;PCOM->Speak(L"I LOVE YOU!", 0, 0);
.endif
invoke ExitProcess,eax
end start
#8
我也不知道50是怎么来的,也问问别人。
按理说,Speak函数是第7个函数,那么实际函数就是第10个函数(接口最开始的还有3个默认函数)
也就是说,偏移量应该是10*4=40=28h才是,但是现在是50h=80,难道每个函数使用的是8个字节?
按理说,Speak函数是第7个函数,那么实际函数就是第10个函数(接口最开始的还有3个默认函数)
也就是说,偏移量应该是10*4=40=28h才是,但是现在是50h=80,难道每个函数使用的是8个字节?
#9
估计是还和参数有关呀
#10
和参数没啥关系,是因为此接口不是直接从IUnknown继承的,
ISpvoice <-- ISpEventSource <-- ISpNotifySource <-- IUnknown
你数数里头的接口数目,正好是第21个接口,也就是相对偏移50h
ISpvoice <-- ISpEventSource <-- ISpNotifySource <-- IUnknown
你数数里头的接口数目,正好是第21个接口,也就是相对偏移50h
#11
正如doudouHuY大哥所教!
谢谢大家帮忙,感激不尽!
谢谢大家帮忙,感激不尽!
#12
你去看看COM原理与应用,里面有说的。就是指针首先是指向VTL,每个虚函数的指针占一定空间,顺着下去就可以了。好像是这样,我当时也没看的太认真。
#1
接口都获得了,直接->Speak就可以了
#2
那用汇编呢,假如EAX是接口的地址,先把Speak的参数PUSH进栈,再CALL DWORD (EAX + 偏移),好像这个偏移是50H,但我自己算不对,哪位大侠来简单再说一说呀,怎么算的!
#3
不懂也
#4
牛啊
#5
怎么没人来帮助我这个菜鸟??
#6
接口指向的地址才是函数地址开始的地方,也就是[EAX]+偏移 才是函数
#7
这是在网上看的别人的例子,编译成功,但不知那个偏移50咋来的!我本愚钝!
.586
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
include ole32.inc
includelib kernel32.lib
includelib ole32.lib
.data
CLSID_SpVoice GUID <096749377h, 03391h, 011D2h, <09Eh, 0E3h, 000h, 0C0h, 04Fh, 079h, 073h, 096h>>
IID_ISpVoice GUID <06C44DF74h, 072B9h, 04992h, <0A1h, 0ECh, 0EFh, 099h, 06Eh, 004h, 022h, 0D4h>>
TEXT db 'I',0,' ',0 ,'L',0 ,'o',0 ,'v',0 ,'e',0 ,' ',0 ,'Y',0 ,'o',0 ,'u',0 ,'!',0,0
.data?
PCOM dd ?
.code
; ---------------------------------------------------------------------------
start:
invoke CoInitialize,0
invoke CoCreateInstance,offset CLSID_SpVoice, 0, CLSCTX_INPROC_SERVER, offset IID_ISpVoice,offset PCOM
.if eax == 0
push 0
push 0
push offset TEXT
mov eax,PCOM
push eax
mov eax,[eax]
call DWORD PTR[eax+50h] ;PCOM->Speak(L"I LOVE YOU!", 0, 0);
.endif
invoke ExitProcess,eax
end start
.586
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
include ole32.inc
includelib kernel32.lib
includelib ole32.lib
.data
CLSID_SpVoice GUID <096749377h, 03391h, 011D2h, <09Eh, 0E3h, 000h, 0C0h, 04Fh, 079h, 073h, 096h>>
IID_ISpVoice GUID <06C44DF74h, 072B9h, 04992h, <0A1h, 0ECh, 0EFh, 099h, 06Eh, 004h, 022h, 0D4h>>
TEXT db 'I',0,' ',0 ,'L',0 ,'o',0 ,'v',0 ,'e',0 ,' ',0 ,'Y',0 ,'o',0 ,'u',0 ,'!',0,0
.data?
PCOM dd ?
.code
; ---------------------------------------------------------------------------
start:
invoke CoInitialize,0
invoke CoCreateInstance,offset CLSID_SpVoice, 0, CLSCTX_INPROC_SERVER, offset IID_ISpVoice,offset PCOM
.if eax == 0
push 0
push 0
push offset TEXT
mov eax,PCOM
push eax
mov eax,[eax]
call DWORD PTR[eax+50h] ;PCOM->Speak(L"I LOVE YOU!", 0, 0);
.endif
invoke ExitProcess,eax
end start
#8
我也不知道50是怎么来的,也问问别人。
按理说,Speak函数是第7个函数,那么实际函数就是第10个函数(接口最开始的还有3个默认函数)
也就是说,偏移量应该是10*4=40=28h才是,但是现在是50h=80,难道每个函数使用的是8个字节?
按理说,Speak函数是第7个函数,那么实际函数就是第10个函数(接口最开始的还有3个默认函数)
也就是说,偏移量应该是10*4=40=28h才是,但是现在是50h=80,难道每个函数使用的是8个字节?
#9
估计是还和参数有关呀
#10
和参数没啥关系,是因为此接口不是直接从IUnknown继承的,
ISpvoice <-- ISpEventSource <-- ISpNotifySource <-- IUnknown
你数数里头的接口数目,正好是第21个接口,也就是相对偏移50h
ISpvoice <-- ISpEventSource <-- ISpNotifySource <-- IUnknown
你数数里头的接口数目,正好是第21个接口,也就是相对偏移50h
#11
正如doudouHuY大哥所教!
谢谢大家帮忙,感激不尽!
谢谢大家帮忙,感激不尽!
#12
你去看看COM原理与应用,里面有说的。就是指针首先是指向VTL,每个虚函数的指针占一定空间,顺着下去就可以了。好像是这样,我当时也没看的太认真。