| 
							Aether
							
						 | 
						
							
								  | 
								
									
									 «  : 04-08-2016 11:39 »   | 
								
								 | 
							  
							 
							Добрый день.
  Спрошу, возможно, кто-то уже сталкивался. Для получения списка функций содержащегося в DLL существуют утилиты, например, tiny_impdef, но, как быть, если в DLL содержится COM объект? Естественно, некоторые из функций, явно объявленные в библиотеке, будут являться создателями некоего базового интерфейса, однако, сколько интерфейсов всего? И второе, у интерфейса есть методы - как построить их таблицу? Третье, является ли позиция того или иного метода в vtable статической, или она может "изменяться"?
  Какую современную литературу по COM стоит изучить? 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							RXL
							
						 | 
						
							
								  | 
								
									
									 « Ответ #1 : 04-08-2016 12:58 »   | 
								
								 | 
							  
							 
							Для зарегистрированных в системе компонент можно посмотреть в панели управление/администрирование/компоненты. 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С. 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							Aether
							
						 | 
						
							
								  | 
								
									
									 « Ответ #2 : 04-08-2016 16:48 »   | 
								
								 | 
							  
							 
							Поясню на примере: есть a.dll. Создаю a.def. Внутри оказывается много чего, но меня интересует функция Create_A_interface(...), которая возвращает интерфейс IA. Как я уже понял, интерфейс - это всего лишь указатель на vtable, который является списком указателей на методы данного COM объекта, соответственно, если мне нужен метод IA_start, то мне нужно не просто знать его имя, а знать его позицию в этом vtable. Изучение заголовочных файлов приводит к конструкции вида: STDMETHOD(IA_start)(...), которая как-то не очень понятно разворачивается... В общем, первое, что захотелось осуществить: узнать механизм распознавания методов? Или ситуацию более полно?
  И ещё, в параметры Create_A_interface входит GUID - 128 бит идентификатор. Если я буду туда посылать не записанный в a.h, GUID_A, а GUID от IUnknown, то соответственно, должен ли я на выходе получить IUnknown от этого COM объекта? Или это зависит от реализации конкретной функции получения интерфейса?
  Извиняюсь за сумбурность, пытаюсь разобраться впервые. 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							zubr
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #3 : 04-08-2016 23:07 »   | 
								
								 | 
							  
							 
							Aether, не имея описания методов, по одной длл - тут только реверс поможет. А так, если есть описание, получил интерфейс вызовом Create_A_interface - это и есть адрес vtable. Зная номер нужного метода, исходя из описания умножаешь его на размер указателя (32/64 бита) - получаешь адрес указателя, который содержит адрес метода. 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							Aether
							
						 | 
						
							
								  | 
								
									
									 « Ответ #4 : 05-08-2016 05:39 »   | 
								
								 | 
							  
							 
							Из описания только заголовочный файл, но он, как понял годится только для MSVC, так как в нём не нахожу явного присваивания методам номеров. Единственное, что есть, конструкции вида: STDMETHOD ...(QueryInterface)(...) STDMETHOD ...(Addref)(...) STDMETHOD ...(Release)(...) Про эти три прочёл уже, что они идут следом строго в одной последовательности, то есть позиции 0, 1, 2. Предположу, что остальное тоже по списку, и буду пробовать. Другое дело, каков нормальный путь к распознаванию или какое описание должно поставляться? Иначе как быть, если нет желания пользоваться MSVC или нужно что-то перевести на asm? 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							zubr
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #5 : 05-08-2016 07:07 »   | 
								
								 | 
							  
							 
							В описании, как правило, последовательность методов, соответствует их в vtable. 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							Aether
							
						 | 
						
							
								  | 
								
									
									 « Ответ #6 : 06-08-2016 07:54 »   | 
								
								 | 
							  
							 
							Да, предположение оказалось правильное: позиции в списке заголовочного файла совпадают с позициями методов в VTable. Вообще очень странная конструкция: для вызова функции необходимо несколько служебных обращений к памяти, и несмотря на работу внутри одного модуля, каждому методу нужно передавать ещё и сам интерфейс. Ладно, главное, что работает.    
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							zubr
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #7 : 06-08-2016 20:32 »   | 
								
								 | 
							  
							 
							Фишка в том, что у com-интерфейса могут быть абстрактные методы, которые ты можешь реализовать сам - отсюда и такая конструкция. 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							Aether
							
						 | 
						
							
								  | 
								
									
									 « Ответ #8 : 07-08-2016 10:05 »   | 
								
								 | 
							  
							 
							Фишка в том, что у com-интерфейса могут быть абстрактные методы, которые ты можешь реализовать сам - отсюда и такая конструкция.
  Если возможно, то на примере. Код приводить не нужно, просто для понимания. На настоящий момент я понимаю так: COM связан с Windows, поэтому внутренняя реализация останется закрытой, по крайней мере, что-то добавить можно лишь там, где это дадут сделать. Второе: как часть DLL редактирование VTable, например, для переадрессации на свою функцию невозможно. Мало того, GUID уникален для каждого интерфейса, и должен оставаться таким. В целом понимаю так: если придерживаться этой концепции, то писать нужно собственный компонент, связывая его известными интерфейсами с другими. Выпуская новую версию компонента, необходимо, присваивать ей новый GUID.  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							Dale
							
						 | 
						
							
								  | 
								
									
									 « Ответ #9 : 07-08-2016 10:41 »   | 
								
								 | 
							  
							 
							Когда-то давно, когда еще работал с COM, ответы на все возникающие вопросы находил в этой книге:  http://www.softzenware.com/downloads/inside_com.pdfПолистайте, может, и на Ваши вопросы она ответит.  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.
  Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard
  Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер. 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							zubr
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #10 : 07-08-2016 12:04 »   | 
								
								 | 
							  
							 
							Если возможно, то на примере. Код приводить не нужно, просто для понимания. На настоящий момент я понимаю так: COM связан с Windows, поэтому внутренняя реализация останется закрытой, по крайней мере, что-то добавить можно лишь там, где это дадут сделать. Второе: как часть DLL редактирование VTable, например, для переадрессации на свою функцию невозможно. Мало того, GUID уникален для каждого интерфейса, и должен оставаться таким. В целом понимаю так: если придерживаться этой концепции, то писать нужно собственный компонент, связывая его известными интерфейсами с другими. Выпуская новую версию компонента, необходимо, присваивать ей новый GUID. К примеру, если надо перехватить события IE, а точнее интерфейса IWebBrowser2, который наследуется от интерфейса IDispath, создается класс наследник IDispath и переопределяется метод Invoke. На низком уровне мы просто получаем адрес этого метода (ведь длл уже загружена в память нашего процесса), и при его выполнении мы получаем нужные параметры, которые уже вставляем в свой метод, к примеру в событие OnDocumentDownload. И почему невозможна переадресация на свою функцию. Находишь в памяти процесса vtable, а данная таблица содержит указатели на методы, что мешает туда прописать адреса на свои функции? Ну только естественно потом надо будет вернуть управление на оригинальный адрес метода. Я такое как-то реализовывал с DirectShow через инжект, причем с чужим процессом.  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							Aether
							
						 | 
						
							
								  | 
								
									
									 « Ответ #11 : 07-08-2016 18:15 »   | 
								
								 | 
							  
							 
							И почему невозможна переадресация на свою функцию. Находишь в памяти процесса vtable, а данная таблица содержит указатели на методы, что мешает туда прописать адреса на свои функции? Я так понимаю, VTable находится в пространстве DLL, и как-то оно должно быть защищено, ведь то, что мы изменим там, измениться и для других задач, её использующих?  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							zubr
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									«  Ответ #12 : 08-08-2016 03:55 »    | 
								
								 | 
							  
							 
							Никак не защищено, да и никак и не защитишь - вся защита установка флагов не для записи, только ничего не мешает изменить протектшион. Естественно, если будешь делать хак vtable, то надо предусмотреть, чтобы только в нужных тебе случаях выполнялся подмененный код.
  З.Ы. Подмену то надо делать уже в процессе, когда длл загружена туда, а не в самом файле длл, тем более в самом файле это бессмысленно. 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
									« Последнее редактирование: 08-08-2016 03:57 от zubr »
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	 |