Форум программистов, компьютерный форум CyberForum.ru

Перехват и подмена вызываемых функций - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Программы на C http://www.cyberforum.ru/cpp/thread46395.html
Известно, что такие системы как PHP, MySQL, Apache и многие другие написаны на языке C. Мне любопытно, действительно их пишут на чистом C? И какой при этом компилятор используют? Вообще где можно почитать (книги, статьи) про программирование и архитектуру подобных систем?
C++ определение расшарености(Share) папки програмно Добрые люди, подскажите пожалуйста как определить, что папка расшарена с помощью Win API програмно? http://www.cyberforum.ru/cpp/thread46292.html
определение расшарености(Share) папки програмно C++
Добрые люди, подскажите пожалуйста как определить, что папка расшарена с помощью Win API програмно?
Поиск в файле C++
Есть большое колличество файлов (word и excel). Как написать программу, которая бы искала введенное сочетание слов во всех файлах и в качестве результата - выводила или открывала данные файлы, или путь к ним показывала....?? помогите плиз, очень надо! Добавлено через 3 минуты 20 секунд пролсто я не совсем понимаю, как это реализовать (именно поиск в файле по введенной комбинации слов)
C++ Начать программирование на C++ http://www.cyberforum.ru/cpp/thread46081.html
Подскажите как начать программмировать на c++ ? Подскажите пожалуйста самую подходящую литературу ! Я учу PHP сейчас ( ну это как бы для вэб и не в счет так же как и то что я знаю HTML ))) Знаю только что c++ является самым серьезным языком программирования (ООП) Спасибо !
C++ Русификация консольных приложений Народ, помогите плиз. Есть ли прога, позволяющая русифицировать консольные приложения на с++? Заранее простите за безграмотность. Изучаю с++ всего 2-й день подробнее

Показать сообщение отдельно
Evg
Эксперт CАвтор FAQ
17462 / 5700 / 361
Регистрация: 30.03.2009
Сообщений: 15,636
Записей в блоге: 26
10.08.2009, 21:07     Перехват и подмена вызываемых функций
Цитата Сообщение от niXman Посмотреть сообщение
Это симлинк на "/lib/libc-2.9.so"
Понятно, видимо старое имя для совместимости оставлено

Цитата Сообщение от niXman Посмотреть сообщение
Еще вопрос.
Как узнать какие функции вызывает функция "fopen", или другие?
Что означают одинарный и двойной подчерки перед названием функции?
Чуть позже отвечу

Цитата Сообщение от niXman Посмотреть сообщение
Я программист С/С++ с 10 летним стажем
Значит всё гораздо проще Но в любом случае всё это - системная специфика. Понятно, что программисту с 10-летним стажем это гораздо проще понять, чем новичку, но просто сразу предупреждаю, что у тебя будут ответы на вопросы, но каких-то полезных знаний таким макаром сложно будет приобрести. Ты выполняешь задачу, которая всё-таки требует понимания специфики всего этого дела. К сожалению, с ходу не могу сказать, где и что можно почитать - я как-то по работе в течение нескольких лет с этим общаюсь, а потому это всё опытным путём добывалось. В любом случае на вопросы отвечу

Цитата Сообщение от niXman Посмотреть сообщение
Да и программированием это особо не назовешь, скорее хак
Да и сам ты всё прекрасно понимаешь, о чём я написал выше

Добавлено через 2 минуты 22 секунды
> Чуть позже отвечу

Просто на работе мы используем немного другие утилиты (самодельные), а потому надо сообразить, как со стандартными работать

Добавлено через 12 минут 15 секунд
В общем как-то не совсем удобно стандартными gnu'шными утилитами работать, но тем не менее. Смотрим выдачу по readelf -s:

Код
   177: 00059220    50 FUNC    GLOBAL DEFAULT   11 fopen@@GLIBC_2.1
Сие означает, что функция находится в файле по адресу 0x59220 и имеет размер 50 (десятичное число) байт

Далее делаем дизассемблер от библиотеки:

Код
$ objdump -d /lib/libc-2.7.so > DD
Далее в файле ищем адрес 59220. Но не имя fopen, потому как зачастую в библиотеках одна и та же процедуры может иметь несколько имён. В моём случае в выдачу дизассемблера попало имя _IO_fopen. В дизассемблере у меня печатаются глобальные имена, к которым обращается процедура fopen. При этом по дизассемблеру видно, что реально код выползает за размеры 50 байт, но также видно, что начиная с 50-го байта идёт пачка nop'ов а потом хрен не пойми чего. Если разбираешься в intel'овском ассемблере, то наверное сможешь и понять, что там делается и откуда дёргается

Щас напишу ещё один вариант - со статической библиотекой. В теории код там должен быть такой же (хотя в некоторых случаях он различается для статической и динамической версий). Но статическая библиотека представляет собой архив отдельных объектных файлов, а потому там копаться иногда проще

Добавлено через 7 минут 14 секунд
Смотрим, из каких файлов состоит статическая библиотека, отфильтруем те, у которых есть fopen в названии

Код
$ ar t /usr/lib/libc.a | grep fopen
iofopen.o
iofopen64.o

Выдираем файл из архива

Код
$ ar x /usr/lib/libc.a iofopen.o   
$ ls iofopen.o 
iofopen.o
Смотрим, какие символы присутсвуют в объектнике

Код
$ readelf -s iofopen.o 

Symbol table '.symtab' contains 23 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 00000000     0 SECTION LOCAL  DEFAULT    1 
     2: 00000000     0 SECTION LOCAL  DEFAULT    3 
     3: 00000000     0 SECTION LOCAL  DEFAULT    4 
     4: 00000000     0 SECTION LOCAL  DEFAULT    5 
     5: 00000000     0 SECTION LOCAL  DEFAULT    7 
     6: 00000000     0 SECTION LOCAL  DEFAULT    8 
     7: 00000000    63 FUNC    GLOBAL DEFAULT    1 __fopen_maybe_mmap
     8: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND _IO_wfile_jumps_maybe_mma
     9: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND _IO_file_jumps_maybe_mmap
    10: 00000040   196 FUNC    GLOBAL DEFAULT    1 __fopen_internal
    11: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND malloc
    12: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND _IO_wfile_jumps
    13: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND _IO_no_init
    14: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND _IO_file_jumps
    15: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND _IO_file_init
    16: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND _IO_file_fopen
    17: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND _IO_un_link
    18: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND free
    19: 00000110    34 FUNC    GLOBAL DEFAULT    1 _IO_new_fopen
    20: 00000110    34 FUNC    GLOBAL DEFAULT    1 __new_fopen
    21: 00000110    34 FUNC    WEAK   DEFAULT    1 _IO_fopen
    22: 00000110    34 FUNC    WEAK   DEFAULT    1 fopen
Всё, что UNDEF - это по сути использование extern'ов. 4 последних - это то, что экспортируется в этом объектнике: символы GLOBAL и WEAK, но не LOCAL (в данном случае их просто нет). Причём видим, что у всех 4 символов совпадает адрес. Т.е. физически мы имеем процедуру, точка входа в которую имеет 4 метки с разными именами, а потому все UNDEF'ы расту из этой процедуры

Добавлено через 4 минуты 12 секунд
Пардон, ошибся. Там ещё есть __fopen_maybe_mmap и __fopen_internal. Т.е. всего три процедуры. И надо разбираться, какие из UNDEF'ов растут из каких процедур

Код
$ readelf -r iofopen.o 

Relocation section '.rel.text' at offset 0x690 contains 13 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
0000001e  00000801 R_386_32          00000000   _IO_wfile_jumps_maybe_
0000002b  00000801 R_386_32          00000000   _IO_wfile_jumps_maybe_
00000039  00000901 R_386_32          00000000   _IO_file_jumps_maybe_m
00000063  00000b02 R_386_PC32        00000000   malloc
00000088  00000c01 R_386_32          00000000   _IO_wfile_jumps
000000a0  00000d02 R_386_PC32        00000000   _IO_no_init
000000aa  00000e01 R_386_32          00000000   _IO_file_jumps
000000b2  00000f02 R_386_PC32        00000000   _IO_file_init
000000c9  00001002 R_386_PC32        00000000   _IO_file_fopen
000000e9  00001102 R_386_PC32        00000000   _IO_un_link
000000f1  00001202 R_386_PC32        00000000   free
0000012c  00000a02 R_386_PC32        00000040   __fopen_internal
000000e1  00000702 R_386_PC32        00000000   __fopen_maybe_mmap

Relocation section '.rel.eh_frame' at offset 0x6f8 contains 2 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
0000001c  00000101 R_386_32          00000000   .text
0000004c  00000101 R_386_32          00000000   .text
Здесь расписаны места, где торчат ссылки на символы (relocation, хз как по русски называется). Например, malloc используется по адресу 0x63, а из предыдущего дампа можно понять, что этот адрес принадлежиьт процедуре __fopen_internal, потому как её стартовый адрес 0x40, а размер 196

Добавлено через 2 минуты 29 секунд
А можно вообще сделать дизассемблеирование, и там всё станет понятно

Код
$ objdump -d iofopen.o 

iofopen.o:     file format elf32-i386

Disassembly of section .text:

00000000 <__fopen_maybe_mmap>:
   0:	55                   	push   %ebp
   1:	89 e5                	mov    %esp,%ebp
   3:	8b 55 08             	mov    0x8(%ebp),%edx
   6:	f6 42 3c 01          	testb  $0x1,0x3c(%edx)
   a:	74 23                	je     2f <__fopen_maybe_mmap+0x2f>
   c:	f6 02 08             	testb  $0x8,(%edx)
   f:	74 1e                	je     2f <__fopen_maybe_mmap+0x2f>
  11:	8b 42 68             	mov    0x68(%edx),%eax
  14:	85 c0                	test   %eax,%eax
  16:	7e 1b                	jle    33 <__fopen_maybe_mmap+0x33>
  18:	c7 82 94 00 00 00 00 	movl   $0x0,0x94(%edx)
  1f:	00 00 00 
  22:	8b 42 58             	mov    0x58(%edx),%eax
  25:	c7 80 b8 00 00 00 00 	movl   $0x0,0xb8(%eax)
  2c:	00 00 00 
  2f:	5d                   	pop    %ebp
  30:	89 d0                	mov    %edx,%eax
  32:	c3                   	ret    
  33:	c7 82 94 00 00 00 00 	movl   $0x0,0x94(%edx)
  3a:	00 00 00 
  3d:	eb e3                	jmp    22 <__fopen_maybe_mmap+0x22>
  3f:	90                   	nop    

00000040 <__fopen_internal>:
  40:	55                   	push   %ebp
  41:	89 e5                	mov    %esp,%ebp
  43:	83 ec 24             	sub    $0x24,%esp
  46:	8b 45 08             	mov    0x8(%ebp),%eax
  49:	89 5d f4             	mov    %ebx,-0xc(%ebp)
  4c:	89 75 f8             	mov    %esi,-0x8(%ebp)
  4f:	8b 75 10             	mov    0x10(%ebp),%esi
  52:	89 7d fc             	mov    %edi,-0x4(%ebp)
  55:	8b 7d 0c             	mov    0xc(%ebp),%edi
  58:	89 45 f0             	mov    %eax,-0x10(%ebp)
  5b:	c7 04 24 60 01 00 00 	movl   $0x160,(%esp)
  62:	e8 fc ff ff ff       	call   63 <__fopen_internal+0x23>
  67:	85 c0                	test   %eax,%eax
  69:	89 c3                	mov    %eax,%ebx
  6b:	0f 84 84 00 00 00    	je     f5 <__fopen_internal+0xb5>
  71:	8d 80 98 00 00 00    	lea    0x98(%eax),%eax
  77:	89 43 48             	mov    %eax,0x48(%ebx)
  7a:	8d 83 a4 00 00 00    	lea    0xa4(%ebx),%eax
  80:	89 44 24 0c          	mov    %eax,0xc(%esp)
  84:	c7 44 24 10 00 00 00 	movl   $0x0,0x10(%esp)
  8b:	00 
  8c:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
  93:	00 
  94:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
  9b:	00 
  9c:	89 1c 24             	mov    %ebx,(%esp)
  9f:	e8 fc ff ff ff       	call   a0 <__fopen_internal+0x60>
  a4:	c7 83 94 00 00 00 00 	movl   $0x0,0x94(%ebx)
  ab:	00 00 00 
  ae:	89 1c 24             	mov    %ebx,(%esp)
  b1:	e8 fc ff ff ff       	call   b2 <__fopen_internal+0x72>
  b6:	89 74 24 0c          	mov    %esi,0xc(%esp)
  ba:	89 7c 24 08          	mov    %edi,0x8(%esp)
  be:	8b 45 f0             	mov    -0x10(%ebp),%eax
  c1:	89 1c 24             	mov    %ebx,(%esp)
  c4:	89 44 24 04          	mov    %eax,0x4(%esp)
  c8:	e8 fc ff ff ff       	call   c9 <__fopen_internal+0x89>
  cd:	85 c0                	test   %eax,%eax
  cf:	74 14                	je     e5 <__fopen_internal+0xa5>
  d1:	89 5d 08             	mov    %ebx,0x8(%ebp)
  d4:	8b 75 f8             	mov    -0x8(%ebp),%esi
  d7:	8b 5d f4             	mov    -0xc(%ebp),%ebx
  da:	8b 7d fc             	mov    -0x4(%ebp),%edi
  dd:	89 ec                	mov    %ebp,%esp
  df:	5d                   	pop    %ebp
  e0:	e9 fc ff ff ff       	jmp    e1 <__fopen_internal+0xa1>
  e5:	89 1c 24             	mov    %ebx,(%esp)
  e8:	e8 fc ff ff ff       	call   e9 <__fopen_internal+0xa9>
  ed:	89 1c 24             	mov    %ebx,(%esp)
  f0:	e8 fc ff ff ff       	call   f1 <__fopen_internal+0xb1>
  f5:	8b 5d f4             	mov    -0xc(%ebp),%ebx
  f8:	31 c0                	xor    %eax,%eax
  fa:	8b 75 f8             	mov    -0x8(%ebp),%esi
  fd:	8b 7d fc             	mov    -0x4(%ebp),%edi
 100:	89 ec                	mov    %ebp,%esp
 102:	5d                   	pop    %ebp
 103:	c3                   	ret    
 104:	8d b6 00 00 00 00    	lea    0x0(%esi),%esi
 10a:	8d bf 00 00 00 00    	lea    0x0(%edi),%edi

00000110 <_IO_new_fopen>:
 110:	55                   	push   %ebp
 111:	89 e5                	mov    %esp,%ebp
 113:	83 ec 0c             	sub    $0xc,%esp
 116:	8b 45 0c             	mov    0xc(%ebp),%eax
 119:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
 120:	00 
 121:	89 44 24 04          	mov    %eax,0x4(%esp)
 125:	8b 45 08             	mov    0x8(%ebp),%eax
 128:	89 04 24             	mov    %eax,(%esp)
 12b:	e8 fc ff ff ff       	call   12c <_IO_new_fopen+0x1c>
 130:	c9                   	leave  
 131:	c3                   	ret
По поводу символов, начинающихся на знак подчерка. По соглашениям (это вроде бы в стандарте прописано) символы, начинающиеся с подчерка зарезервированы для системных нужд и пользователь невправе создавать в своём приложении глобалы с именами, начинающимися на подчерк. Это гарантирует, что наличие нестандартных глобальных имён в библиотеке не будет конфликтовать с пользовательскими именами

Добавлено через 1 минуту 58 секунд
Не, с дизассемблером лажа, там использование внешних имён не подставляется. Так что вычислять надо, как я указал выше - по двум дампам "readelf -s" и "readelf -r"
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru