helldrg Опубликовано 4 октября, 2016 Поделиться Опубликовано 4 октября, 2016 Здравствуйте! Хотел записать переход по jmp даже порядок записи изменил байтов, заметил такую особенность: Bytes Opcode 088A0000 - E9 088A0000 - jmp 088A8A0D В Bytes все правильно записывается 0xe9 - команда безусловного перехода и адрес перехода 088A0000. В итоге должно получится зацикливание (только сейчас заметил =)). Но в Opcode адрес перехода другой 088A8A0D. Почему так? Ссылка на комментарий Поделиться на другие сайты Поделиться
gmz Опубликовано 4 октября, 2016 Поделиться Опубликовано 4 октября, 2016 там не прямой адрес. вот например: Скрытый текст .lulz: lea eax,[.zz] ;адрес для jmp sub eax,0x400000 ;в даном случае база модуля lea ecx,[.kk+5] ;адрес jmp +его размер sub ecx,0x400000 sub eax,ecx ;получаем новый адрес для jmp mov [.kk+1],eax ;пишем .zz: nop .kk: jmp near .lulz так что у тебя должно быть 0-5=FFFFFFFB типа E9 FBFFFFFF 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
Dino Опубликовано 4 октября, 2016 Поделиться Опубликовано 4 октября, 2016 это относительных переход и рассчитывается по формуле <Адрес куда прыгаем> - <Адрес от куда прыгаем> - <Количество байт занятых под команду jmp> то бишь 0x088A0000 - 0x088A0000 - 2 тк это near jmp, то он будет занимать 2 байт в итоге получаем EB FE 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
helldrg Опубликовано 4 октября, 2016 Автор Поделиться Опубликовано 4 октября, 2016 Воууу, почему так сложно =) Тоесть что бы попасть с адреса на адрес 0x088A0000 нужно вписать jmp EB FE ? там кстати если так делать четыре 0 дописывается Ссылка на комментарий Поделиться на другие сайты Поделиться
keng Опубликовано 4 октября, 2016 Поделиться Опубликовано 4 октября, 2016 Еще можно прыгать на + или - сколько-нибудь байт вперед. Типа "jmp 5" - вперед (ниже по коду) на 5 байт. CE, по-моему, даже умеет автоматически определять разницу между short jmp и far jmp. А "почему так сложно" - наоборот, просто, все переходы - статические. Код лежит всегда по одним и тем же относительным смещениям, так компилятор делает и так процессору проще в этой каше разбираться. Как результат - программы работают быстрее. 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
helldrg Опубликовано 4 октября, 2016 Автор Поделиться Опубликовано 4 октября, 2016 Сложность в том состоит, что вот к примеру: 05F70000 - E9 05F70000 - jmp 05F7F70A если писать E9 EB FE(я так понял это как раз и будет зацикливание, потому что <Адрес куда прыгаем> - <Адрес от куда прыгаем> равняется 0, а - 2 байта тут говорят равняется EB FE), то еще появятся 00 00. Че то я вообще не доганяю Ссылка на комментарий Поделиться на другие сайты Поделиться
Dino Опубликовано 4 октября, 2016 Поделиться Опубликовано 4 октября, 2016 2 минуты назад, keng сказал: Еще можно прыгать на + или - сколько-нибудь байт вперед. Типа "jmp 5" - вперед (ниже по коду) на 5 байт. CE, по-моему, даже умеет автоматически определять разницу между short jmp и far jmp. А "почему так сложно" - наоборот, просто, все переходы - статические. Код лежит всегда по одним и тем же относительным смещениям, так компилятор делает и так процессору проще в этой каше разбираться. Как результат - программы работают быстрее. Да конечно умеет. Но я понимаю стремление ТСа самому разобраться в этом. 17 минуту назад, helldrg сказал: Воууу, почему так сложно =) Тоесть что бы попасть с адреса на адрес 0x088A0000 нужно вписать jmp EB FE ? там кстати если так делать четыре 0 дописывается Ноу. EB - это и есть код команды short jmp (short\near одно и тоже) FE - это относительное смещение , которое ты высчитал по формуле 11D70000 EB FE - jmp 11D70000 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
helldrg Опубликовано 4 октября, 2016 Автор Поделиться Опубликовано 4 октября, 2016 Спасибо большое! Буду отталкиваться от этого дальше!!! Ссылка на комментарий Поделиться на другие сайты Поделиться
helldrg Опубликовано 4 октября, 2016 Автор Поделиться Опубликовано 4 октября, 2016 (изменено) Dino Спасибо большое еще раз! Я вроде как разобрался, теперь использую E9 - это наверно far jmp =) Скрытый текст BYTE *bytes = new BYTE[20]; DWORD jmpAddress = allocAddress - (baseAddress + offsetAddress[2]) - 5; BYTE *b = new BYTE[4]; memcpy((void*)b, &jmpAddress, 4); bytes[0] = '\xe9'; bytes[1] = b[0]; bytes[2] = b[1]; bytes[3] = b[2]; bytes[4] = b[3]; bytes[5] = '\x90'; bytes[6] = '\x90'; if (Process.WriteMemory(baseAddress + offsetAddress[2], (LPVOID)bytes, 7) == FALSE) wsprintf(buffer, "Ошибка!"); jmpAddress = (baseAddress + offsetAddress[2]) - allocAddress - 19 + 7; memcpy((void*)b, &jmpAddress, 4); bytes[0] = '\xc7'; bytes[1] = '\x46'; bytes[2] = '\xc8'; bytes[3] = '\x00'; bytes[4] = '\x00'; bytes[5] = '\x16'; bytes[6] = '\x44'; bytes[7] = '\xd9'; bytes[8] = '\x46'; bytes[9] = '\xc8'; bytes[10] = '\x8a'; bytes[11] = '\x5c'; bytes[12] = '\x24'; bytes[13] = '\x17'; bytes[14] = '\xe9'; bytes[15] = b[0]; bytes[16] = b[1]; bytes[17] = b[2]; bytes[18] = b[3]; if (Process.WriteMemory(allocAddress, (LPVOID)bytes, 19) == FALSE) wsprintf(buffer, "Ошибка!"); Вот такое чудовище получилось, но оно работает :DD Спасибо за терпение к моей не образованности!!! Спасибо kengу за замечательные уроки!!! Изменено 4 октября, 2016 пользователем helldrg 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
helldrg Опубликовано 4 октября, 2016 Автор Поделиться Опубликовано 4 октября, 2016 GMZ Цитата так что у тебя должно быть 0-5=FFFFFFFB типа E9 FBFFFFFF До меня только сейчас эта строчка дошла =) Спасибо! 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
Dino Опубликовано 4 октября, 2016 Поделиться Опубликовано 4 октября, 2016 походу я соврал насчет short и near - это не одно и тоже http://x86.renejeschke.de/html/file_module_x86_id_147.html 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
Xipho Опубликовано 5 октября, 2016 Поделиться Опубликовано 5 октября, 2016 Ребята, в современной модели памяти, когда все расположено в одном сегменте, far не имеет смысла. Это всегда будет near, если мне не изменяет память. Ссылка на комментарий Поделиться на другие сайты Поделиться
keng Опубликовано 5 октября, 2016 Поделиться Опубликовано 5 октября, 2016 4 hours ago, Xipho said: Ребята, в современной модели памяти, когда все расположено в одном сегменте, far не имеет смысла. Это всегда будет near, если мне не изменяет память. Изменяет, т.к. это зависит только от размера. Near - это +-127 байт от EIP. Верхняя же планка, по-моему, стоит в 4 Гб. Ссылка на комментарий Поделиться на другие сайты Поделиться
Xipho Опубликовано 6 октября, 2016 Поделиться Опубликовано 6 октября, 2016 Может, я по старой памяти путаю near и short. Ссылка на комментарий Поделиться на другие сайты Поделиться
keng Опубликовано 6 октября, 2016 Поделиться Опубликовано 6 октября, 2016 1 hour ago, Xipho said: Может, я по старой памяти путаю near и short. Short - это динозавр, который позволяет прыгать только на 8 бит (???). Near - +-127 байт, т.е. 8, 16 или 32 бита. Far - дальше или в другой сегмент. У меня тут возник вопрос - какой будет опкод, если прыгать надо недалеко (до 127), но в соседний сегмент? Far? Ссылка на комментарий Поделиться на другие сайты Поделиться
Xipho Опубликовано 7 октября, 2016 Поделиться Опубликовано 7 октября, 2016 Far, разумеется. Вообще, сколько я копался в современных приложениях, везде та же олька ставит jmp short (или near, не помню, надо будет посмотреть), поскольку память в винде уже с лохматых времен плоская. Это в досе и вин до 95 память была сегментированной. И, если мне не изменяет память, в ДОСе размер сегмента не мог превышать 64 килобайта. А командные интерпретаторы типа command.com по каким-то ограничениям обязаны были состоять из одного сегмента, и потому их размер ну никак не мог превышать те самые 64 килобайта. Добавлено: Собственно. near - в одном сегменте. far - за пределы сегмента http://x86.renejeschke.de/html/file_module_x86_id_147.html Ссылка на комментарий Поделиться на другие сайты Поделиться
keng Опубликовано 7 октября, 2016 Поделиться Опубликовано 7 октября, 2016 Плоская память - это про виртуальную. Сам бинарник мапится на физическую память согласно секциям, которые не могут быть больше 4Гб. Вот как раз при расчете адреса для прыжка между секциями (или между модулями бинарника, если это надо) и будет short или far. Плоская память позволяет адресануться гигов за 10 и винда не подавится, иначе бы пришлось пересчитывать все смещения. Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения