Delphi Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
델파이 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
FreePascal/Lazarus
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
델마당
볼랜드포럼 광고 모집

델파이 Q&A
Delphi Programming Q&A
[14718] Re:Re: COM을 어셈블러로 코딩하시다니 헐~
델파이 [] 2193 읽음    2013-06-22 16:11
열심히 분석해보고 있는데 실력이 짧아서 해메고있네요. COM을 어셈블러로 코딩하시다니 헐~ 완전 감동 먹었습니다


지나다가 님이 쓰신 글 :
: 엠바카데로의 터보 어셈블러가 버그가 있어서, MS사의 매크로 어셈블러로 작성한 것임.
: TASM으로는 64bit Structured Exception Handling 코드도 작성할 수 없음.
:
: 엠바 애들 물건을 이런 식으로 개판으로 만들면서 돈 받고 팔아 먹는거 보면 신기함 ㅋ
:
: 다음은 MS 매크로 어셈블러로 작성한 소스코드임.
:
:
: 	
: 	.686P
: 	.XMM
: 	.model	flat
: 
: 	EXTRN	_setlocale:PROC
: 	EXTRN	_PKEY_Device_FriendlyName:BYTE
: 	EXTRN	__imp__PropVariantClear@4:PROC
: 	EXTRN	__imp__CoInitialize@4:PROC
: 	EXTRN	_printf:PROC
: 	EXTRN	_atoi:PROC
: 	EXTRN	__imp__CoCreateInstance@20:PROC
: 
: STATICDATA	SEGMENT
: 
: __GUID_f8679f50_850a_41cf_9c72_430f290290c8 DD 0f8679f50H
: 	DW	0850aH
: 	DW	041cfH
: 	DB	09cH
: 	DB	072H
: 	DB	043H
: 	DB	0fH
: 	DB	029H
: 	DB	02H
: 	DB	090H
: 	DB	0c8H
: 
: __GUID_a95664d2_9614_4f35_a746_de8db63617e6 DD 0a95664d2H
: 	DW	09614H
: 	DW	04f35H
: 	DB	0a7H
: 	DB	046H
: 	DB	0deH
: 	DB	08dH
: 	DB	0b6H
: 	DB	036H
: 	DB	017H
: 	DB	0e6H
: 
: __GUID_bcde0395_e52f_467c_8e3d_c4579291692e DD 0bcde0395H
: 	DW	0e52fH
: 	DW	0467cH
: 	DB	08eH
: 	DB	03dH
: 	DB	0c4H
: 	DB	057H
: 	DB	092H
: 	DB	091H
: 	DB	069H
: 	DB	02eH
: 
: __GUID_870af99c_171d_4f9e_af0d_e63df40c2bc9 DD 0870af99cH
: 	DW	0171dH
: 	DW	04f9eH
: 	DB	0afH
: 	DB	0dH
: 	DB	0e6H
: 	DB	03dH
: 	DB	0f4H
: 	DB	0cH
: 	DB	02bH
: 	DB	0c9H
: 
: sLocale DB 'kor', 00H
: sDevN DB 'Device Number[%d]: %ws', 0aH, 00H
: 
: sCurDev DB 0aH, 'Current Default Device: %ws', 0aH, 0aH, 00H
: STATICDATA	ENDS
: 
: PUBLIC	_main
: _TEXT	SEGMENT
: _devConfig@@ = -4		
: 
: myChangeInternalDevice PROC	
: 
: 	push	ecx
: 	push	esi
: 
: 	lea	eax, DWORD PTR _devConfig@@[esp+8]
: 	push	eax
: 	push	OFFSET __GUID_f8679f50_850a_41cf_9c72_430f290290c8
: 	push	23				
: 	push	0
: 	push	OFFSET __GUID_870af99c_171d_4f9e_af0d_e63df40c2bc9
: 	mov	esi, ecx
: 	call	DWORD PTR __imp__CoCreateInstance@20
: 
: 	test	eax, eax
: 	js	SHORT @@noAction
: 
: 	mov	eax, DWORD PTR _devConfig@@[esp+8]
: 	push	1
: 	mov	ecx, DWORD PTR [eax]
: 	push	esi
: 	push	eax
: 	call	DWORD PTR [ecx+52]
: 
: 	mov	ecx, DWORD PTR _devConfig@@[esp+8]
: 	push	ecx
: 	mov	edx, DWORD PTR [ecx]
: 	mov	esi, eax
: 	call	DWORD PTR [edx+8]
: 
: @@noAction:
: 
: 	pop	esi
: 	pop	ecx
: 	ret	
: myChangeInternalDevice ENDP	
: 
: 
: _Device@@ = -28		
: _Store@@ = -24			
: _friendlyName@@ = -20	
: 
: myPrintDefaultDevice PROC
: 
: 	sub	esp, 28	
: 
: 	mov	eax, DWORD PTR [ecx]
: 	lea	edx, DWORD PTR _Device@@[esp+28]
: 	push	edx
: 	push	1
: 	push	0
: 	push	ecx
: 	mov	DWORD PTR _Device@@[esp+44], 0
: 	call	DWORD PTR [eax+16]
: 
: 	mov	eax, DWORD PTR _Device@@[esp+28]
: 	lea	edx, DWORD PTR _Store@@[esp+28]
: 	push	edx
: 	mov	DWORD PTR _Store@@[esp+32], 0
: 	mov	ecx, DWORD PTR [eax]
: 	push	0
: 	push	eax
: 	call	DWORD PTR [ecx+16]
: 
: 	mov	eax, DWORD PTR _Device@@[esp+28]
: 	push	eax
: 	mov	ecx, DWORD PTR [eax]
: 	call	DWORD PTR [ecx+8]
: 
: 	mov	eax, DWORD PTR _Store@@[esp+28]
: 	lea	edx, DWORD PTR _friendlyName@@[esp+28]
: 	xorps	xmm0, xmm0
: 	push	edx
: 	movq	QWORD PTR _friendlyName@@[esp+32], xmm0
: 	movq	QWORD PTR _friendlyName@@[esp+40], xmm0
: 	mov	ecx, DWORD PTR [eax]
: 	push	OFFSET _PKEY_Device_FriendlyName
: 	push	eax
: 	call	DWORD PTR [ecx+20]
: 
: 	mov	eax, DWORD PTR _Store@@[esp+28]
: 	push	eax
: 	mov	ecx, DWORD PTR [eax]
: 	call	DWORD PTR [ecx+8]
: 
: 	push	DWORD PTR _friendlyName@@[esp+36]
: 	push	OFFSET sCurDev
: 	call	_printf
: 	add	esp, 8
: 
: 	lea	eax, DWORD PTR _friendlyName@@[esp+28]
: 	push	eax
: 	call	DWORD PTR __imp__PropVariantClear@4
: 
: 	add	esp, 28			
: 	ret
: myPrintDefaultDevice ENDP
: 
: 
: _Device$$ = -44	
: _Enum$$ = -40		
: _Store$$ = -36		
: _loopCount$$ = -32	
: _Devices$$ = -28	
: _Param$$ = -24		
: _devID$$ = -20		
: _friendlyName$$ = -16	
: 
: _main	PROC
: 	push	ebp
: 	mov	ebp, esp
: 
: 	and	esp, 0fffffff0H
: 	sub	esp, 56	
: 	push	esi
: 	push	edi
: 
: 	push	OFFSET sLocale
: 	push	0
: 	call	_setlocale
: 	add	esp, 8
: 
: 	cmp	DWORD PTR [ebp+8], 2
: 	mov	DWORD PTR _Param$$[esp+64], -1
: 	jne	SHORT @@skipParam
: 	mov	eax, DWORD PTR [ebp+12]
: 	push	DWORD PTR [eax+4]
: 	call	_atoi
: 	add	esp, 4
: 	mov	DWORD PTR _Param$$[esp+64], eax
: 
: @@skipParam:
: 
: 	push	0
: 	call	DWORD PTR __imp__CoInitialize@4
: 	mov	esi, eax
: 
: 	mov	DWORD PTR _Enum$$[esp+64], 0
: 
: 	test	esi, esi
: 	js	@@fail
: 
: 	lea	eax, DWORD PTR _Enum$$[esp+64]
: 	push	eax
: 	push	OFFSET __GUID_a95664d2_9614_4f35_a746_de8db63617e6
: 	push	23		
: 	push	0
: 	push	OFFSET __GUID_bcde0395_e52f_467c_8e3d_c4579291692e
: 	call	DWORD PTR __imp__CoCreateInstance@20
: 	mov	esi, eax
: 
: 	test	esi, esi
: 	js	@@fail
: 
: 	mov	eax, DWORD PTR _Enum$$[esp+64]
: 	lea	edx, DWORD PTR _Devices$$[esp+64]
: 	mov	ecx, DWORD PTR [eax]
: 	push	edx
: 	push	1
: 	push	0
: 	push	eax
: 	call	DWORD PTR [ecx+12]
: 	mov	esi, eax
: 
: 	test	esi, esi
: 	js	@@fail
: 
: 	mov	eax, DWORD PTR _Devices$$[esp+64]
: 	lea	edx, DWORD PTR _loopCount$$[esp+64]
: 	mov	DWORD PTR _loopCount$$[esp+64], 0
: 	mov	ecx, DWORD PTR [eax]
: 	push	edx
: 	push	eax
: 	call	DWORD PTR [ecx+12]
: 
: 	xor	edi, edi
: 	cmp	DWORD PTR _loopCount$$[esp+64], edi
: 	jbe	@@fail
: 
: @@loop:
: 
: 	mov	eax, DWORD PTR _Devices$$[esp+64]
: 	lea	edx, DWORD PTR _Device$$[esp+64]
: 	push	edx
: 	mov	DWORD PTR _Device$$[esp+68], 0
: 	mov	ecx, DWORD PTR [eax]
: 	push	edi
: 	push	eax
: 	call	DWORD PTR [ecx+16]
: 	mov	esi, eax
: 
: 	test	esi, esi
: 	js	@@skip
: 
: 	mov	eax, DWORD PTR _Device$$[esp+64]
: 	lea	edx, DWORD PTR _devID$$[esp+64]
: 	mov	DWORD PTR _devID$$[esp+64], 0
: 	mov	ecx, DWORD PTR [eax]
: 	push	edx
: 	push	eax
: 	call	DWORD PTR [ecx+20]
: 	mov	esi, eax
: 
: 	test	esi, esi
: 	js	@@skip
: 
: 	mov	eax, DWORD PTR _Device$$[esp+64]
: 	lea	edx, DWORD PTR _Store$$[esp+64]
: 	push	edx
: 	mov	DWORD PTR _Store$$[esp+68], 0
: 	mov	ecx, DWORD PTR [eax]
: 	push	0
: 	push	eax
: 	call	DWORD PTR [ecx+16]
: 	mov	esi, eax
: 
: 	test	esi, esi
: 	js	SHORT @@skip
: 
: 	mov	eax, DWORD PTR _Device$$[esp+64]
: 	push	eax
: 	mov	ecx, DWORD PTR [eax]
: 	call	DWORD PTR [ecx+8]
: 
: 	mov	eax, DWORD PTR _Store$$[esp+64]
: 	lea	edx, DWORD PTR _friendlyName$$[esp+64]
: 	push	edx
: 	xorps	xmm0, xmm0
: 	movdqa	XMMWORD PTR _friendlyName$$[esp+68], xmm0
: 	mov	ecx, DWORD PTR [eax]
: 	push	OFFSET _PKEY_Device_FriendlyName
: 	push	eax
: 	call	DWORD PTR [ecx+20]
: 	mov	esi, eax
: 
: 	test	esi, esi
: 	js	SHORT @@skip
: 
: 	mov	eax, DWORD PTR _Store$$[esp+64]
: 	push	eax
: 	mov	ecx, DWORD PTR [eax]
: 	call	DWORD PTR [ecx+8]
: 
: 	push	DWORD PTR _friendlyName$$[esp+72]
: 	push	edi
: 	push	OFFSET sDevN
: 	call	_printf
: 	add	esp, 12	
: 
: 	lea	eax, DWORD PTR _friendlyName$$[esp+64]
: 	push	eax
: 	call	DWORD PTR __imp__PropVariantClear@4
: 
: 	cmp	edi, DWORD PTR _Param$$[esp+64]
: 	jne	SHORT @@skip
: 
: 	mov	ecx, DWORD PTR _devID$$[esp+64]
: 	call	myChangeInternalDevice 
: 
: @@skip:
: 
: 	inc	edi
: 	cmp	edi, DWORD PTR _loopCount$$[esp+64]
: 	jb	@@loop
: 
: @@fail:
: 
: 	mov	eax, DWORD PTR _Devices$$[esp+64]
: 	push	eax
: 	mov	ecx, DWORD PTR [eax]
: 	call	DWORD PTR [ecx+8]
: 
: 	mov	ecx, DWORD PTR _Enum$$[esp+64]
: 	call	myPrintDefaultDevice
: 
: 	mov	eax, DWORD PTR _Enum$$[esp+64]
: 	push	eax
: 	mov	ecx, DWORD PTR [eax]
: 	call	DWORD PTR [ecx+8]
: 
: 	pop	edi
: 	mov	eax, esi
: 	pop	esi
: 	mov	esp, ebp
: 	pop	ebp
: 	ret	0
: _main	ENDP
: _TEXT	ENDS
: 	END
: 

:
: Visual Studio 개발환경 Command Prompt 창 열어 놓고, 아래와 같이 build.bat을 실행하면 컴파일/링크가 될 것임.
:
:
:
:
: 파라미터 없이 다음과 같이 test.exe 를 실행하면, 현재 PC에 있는 Audio Endpoint Device 들이 출력될 것임.
: 내컴엔 메인보드 내장형의 리얼텍과 사운드 블라스트가 같이 설치되어 있고, 기본 사운드 장치로 사블의 SPDIF가
: 선택되어 있는 상태임.
:
:
:
:
: 이 상태에서 "test 2"로 Device Number가 2인 장치를 선택하도록 파라미터를 넘겨주면 다음과 같이 기본 사운드 장치가 바뀌게 됨.
:
:
:
:
: COM을 프로그래밍 해본 경험이 있다면, 작성된 소스 코드를 이해하는데 별 어려움이 없을 것임. 파일도 같이 첨부함.
:
: 사족으로 낼모레면 환갑인 사람도 이렇게 닭짓을 하는데, 젊은 사람이 그렇게 노력 없이 거저 먹으려고 하는 건 ㅋ
:
:
:
:
:
:
: 하두고 님이 쓰신 글 :
: : 로그인을 안했더니 이름 없이 답변이 올라가네요.
: : 버그인가? 아니면 마음씨 좋은 관리자님의 배려?
: :
: : 힌트를 주셔서 감사하구요.
: :
: : 너무 거저 먹으려 해서 죄송 한데요.
: : 혹시 테스트했던 자료가 남아 있으면 주실 수 없는지요?
: :
: :  님이 쓰신 글 :
: : : 헐....
: : : 그 어려운걸 저보고 하라니요....
: : : 나 이제 죽었다....
: : :
: : : 그래도 캄캄했는데 힌트라도 주시니 감사합니다.
: : :
: : : 지나다가 님이 쓰신 글 :
: : : : COM 오브젝트를 인젝션해서 분석해 보면 답이 나옴 ㅋ.
: : : :
: : : : 기본 사운드 장치 선택은 rundll32.exe 라는 호스트 프로세스에 의해서 로드 되는 mmsys.cpl 이라는
: : : : Control Panel Applet에 의해서 선택되게 되어있고,
: : : :
: : : : class GUID가 870af99c_171d_4f9e_af0d_e63df40c2bc9 인 COM 객체를 통해서,
: : : : GUID가 f8679f50_850a_41cf_9c72_430f290290c8 인 Interface 를 취하고 있음.
: : : :
: : : : MS사에서 이와 관련한 COM Interface에 대한 헤더파일을 제공하고 있지 않기 때문에 Interface 이름에 대해선 알수 없지만
: : : : 내부적으로 사용하는 이름이 SetDefaultEndpointDevice? 정도가 아닐까 하는 추론이 가능함.
: : : :
: : : : GUID가 f8679f50_850a_41cf_9c72_430f290290c8 인 COM Interface의 Virtual Method Table을 분석해 보면
: : : : 도합 12개의 Virtual Method를 정의해서 사용하고 있는 것을 알수 있는데,
: : : :
: : : : 이중 0 기준으로 10번째 인덱스로 정의 되어 있는 인터페이스 버추얼 메소드가 사운드 기본장치를 선택하는데 사용되고 있음
: : : :
: : : : IMMDeviceEnumerator 로 얻은 스트롱 네임의 Endpoint Device ID 중에 하나를 파라미터로 이 인터페이스에 Dummy 값 하나와
: : : : 같이 넘겨주면 제어판 경유 없이, 다이렉트로 프로그래밍 방법으로 강제적으로 원하는 기본 사운드 장치를 선택할 수 있음.
: : : :
: : : : 테스트 해보니까 Win7, Win8 다 먹힘 ㅋ
: : : :
: : : :
: : : :
: : : :
: : : :
: : : :
: : : :
: : : :
: : : : 하두고 님이 쓰신 글 :
: : : : : 그냥 제어판의 사운드창을 백그라운드에 띄워놓고
: : : : : 창에 나열된 사운드 장치 정보를 읽어서
: : : : : 선택한 후 [기본장치]버튼을 눌러주도록 해서 처리했습니다.
: : : : : 뭐 간단하게 해결되네요.
: : : : :
: : : : : 하지만 문제는 사운드 장치 이름만 읽어오고
: : : : : 장치 이름 아래 있는 설명을 읽어올 수 없어 사운드 장치가 모두 "스피커"라고 표시되서
: : : : : 도데체 어느 스피커가 어떤 사운드 장치의 스피커인지 알 수가 없네요.
: : : : :
: : : : : 리버스엔지니어링 님이 쓰신 글 :
: : : : : : 윈도우에서 디폴트 사운드 장치를 선택하는 방법은 제어판을 통한 방법 밖에 없습니다
: : : : : : MS에서 그런 API를 제공했다간 사운드카드 만드는 회사들이 경쟁적으로 자기들 카드를 디폴트 사운드장치로
: : : : : : 설정하려는 사태가 벌어지겠죠. 여러 사운드장치 중 하나로 웨이브 데이타가 출력되게 할수는 있어도 시스템 디폴트
: : : : : : 사운드장치를 선택해주는 API는 없습니다.
: : : : : :
: : : : : : 해결 방법은 비스타 이후 COM으로 바뀐 윈도우 오디오 아키텍쳐를 리버스엔지니어링으로 해킹하는 방법 밖에는 없습니다.
: : : : : : COM은 일반적인 API처럼 노출되는게 아니라 해킹하기도 쉽지 않습니다. 그럼에도 불구하고 정 필요하고 패이 조건이 맞으면
: : : : : : 리버스엔지니어링으로 해킹해 드릴 수는 있습니다
: : : : : :
: : : : : :
: : : : : :
: : : : : : 하두고 님이 쓰신 글 :
: : : : : : : 앞에서 했던 질문인데 시원한 답변이 없어 여기 저기 돌아다니며  찾은 소스코드입니다.
: : : : : : : 아래 소스코드는 피시에 장착된 사운드장치를 나열하는 소스코드인데요.
: : : : : : :
: : : : : : : 아래 소스에서 나열된 사운드장치를 선택하여 더블클릭하면
: : : : : : : 해당 사운드장치가 윈도우 기본 사운드장치로 바뀌게 하고 싶은데요.
: : : : : : :
: : : : : : : 기본 사운드 장치를 바꾸는 방법을 모르겠습니다.
: : : : : : :
: : : : : : : procedure TForm1.EnumAudioDevices;
: : : : : : : var
: : : : : : :   dsCreateDevEnum  : ICreateDevEnum;
: : : : : : :   EnumDevice       : IEnumMoniker;
: : : : : : :   DeviceMoniker    : IMoniker;
: : : : : : :   Data             : Integer;
: : : : : : :   DevicePropBag    : IPropertyBag;
: : : : : : :   DeviceName       : OLEVariant;
: : : : : : : begin
: : : : : : :   If CoCreateInstance(CLSID_SystemDeviceEnum,nil,CLSCTX_INPROC_SERVER,IID_ICreateDevEnum,dsCreateDevEnum) = S_OK then
: : : : : : :   Begin
: : : : : : :     If dsCreateDevEnum.CreateClassEnumerator(CLSID_AudioRendererCategory,EnumDevice,0) = S_OK then
: : : : : : :     Begin
: : : : : : :       EnumDevice.Reset;
: : : : : : :       While EnumDevice.Next(1,DeviceMoniker,@Data) = S_OK do
: : : : : : :       Begin
: : : : : : :         If DeviceMoniker.BindToStorage(nil,nil,IID_IPropertyBag,DevicePropBag) = NOERROR then
: : : : : : :         Begin
: : : : : : :           If DevicePropBag.Read('FriendlyName',DeviceName,nil) = NOERROR then
: : : : : : :              IF Copy(DeviceName, 1, Length('DirectSound')) = 'DirectSound' Then
: : : : : : :                 ListBox1.Items.Add(Copy(DeviceName, Length('DirectSound: ') + 1, Length(DeviceName) - Length('DirectSound: ')));
: : : : : : :           DevicePropBag := nil;
: : : : : : :         End;
: : : : : : :         DeviceMoniker := nil;
: : : : : : :       End;
: : : : : : :       EnumDevice := nil;
: : : : : : :     End;
: : : : : : :     dsCreateDevEnum := nil;
: : : : : : :   End;
: : : : : : : End;

+ -

관련 글 리스트
14707 사운드장치 리스트 소스코드입니다. 여기서 기본 사운드장치 설정 방법 좀 알려주세요. 하두고 2657 2013/06/14
14709     Re: 뭔가 착각하고 있나 보네요 리버스엔지니어링 2117 2013/06/17
14710         Re:Re: 뭔가 착각하고 있나 보네요 하두고 2078 2013/06/17
14711             Re: COM 오브젝트를 인젝션해서 분석해보면 답이 나옴 지나다가 2229 2013/06/19
14712                 Re:Re: COM 오브젝트를 인젝션해서 분석해보면 답이 나옴 2072 2013/06/19
14713                     Re:Re:Re: COM 오브젝트를 인젝션해서 분석해보면 답이 나옴 하두고 1970 2013/06/19
14714                         Re: COM 코드 어셈블러로 작성한 것임 지나다가 2334 2013/06/20
14718                             Re:Re: COM을 어셈블러로 코딩하시다니 헐~ 델파이 2193 2013/06/22
14716                             Re:Re: 인젝션이 안 걸리는데요? 궁금이 1932 2013/06/20
14717                                 Re:Re:Re: 인젝션이 안 걸리는데요? 지나다가 2206 2013/06/20
14715                             Re:Re: 어셈코드 올려서 약올리는거 같아서 ... Lyn 2220 2013/06/20
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.