Форум программистов, компьютерный форум, киберфорум
Наши страницы
Assembler для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.54/13: Рейтинг темы: голосов - 13, средняя оценка - 4.54
WinstonCherchil
7 / 7 / 2
Регистрация: 20.01.2011
Сообщений: 73
#1

Ассемблерная вставка, С++

19.11.2014, 11:37. Просмотров 2422. Ответов 25
Метки нет (Все метки)

Доброе утро.

Достался "по наследству" код

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
__declspec(dllexport) int __stdcall NtUserPostMes(HWND hWnd, unsigned int Msg, WPARAM wParam, LPARAM lParam)
{
    
    __asm pop ebp
    __asm mov eax, 0x11fe
    __asm call SystemCall
        __asm retn 0x10
        __asm SystemCall:
    __asm mov edx, esp
    __asm _emit 0x0f
    __asm _emit 0x34
    
}
Этот код изначально был на Дельфи, который благодаря гуглу, я смог перевести в С++ и скомпилить в Студии, однако, его очень сложно добавить в мой проект QT+Mingw. Гугл говорит надо переписать в AT&T Синтаксис эту вставку, но у меня не получилось.

Вобщем прошу помочь переписать его либо в AT&T, что бы MinGW скомпилил, либо (идеальный вариант) переписать в С++

Зарание спасибо.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.11.2014, 11:37
Ответы с готовыми решениями:

Не работает ассемблерная вставка
Здравствуйте! Прблема следующего характера. Пишу проект на С++ в среде...

Ассемблерная вставка из 10 строк в код с++
Доброго времени суток, уважаемые товарищи! В проекте на с++, который передали...

Вычислить выражение (ассемблерная вставка)
Не могу понять как исправить ошибки. Программа работает неправильно при...

Транспонирование матрицы (Ассемблерная вставка)
На Си создать с помощью датчика случайных чисел(random) файл F1 с...

Ассемблерная вставка, реализующая вычитание
вообщем вот #include <stdio.h> // необходим для работы printf #include...

25
Mikl___
Автор FAQ
11730 / 6042 / 543
Регистрация: 11.11.2010
Сообщений: 11,025
19.11.2014, 12:16 #2
WinstonCherchil,
попытайся переводить по одной строке, основное различие - это обратный порядок операндов и указание типа операндов в названии операции, то есть sub edx, 16 = subl $16,%edx точность не гарантирую но по моему так
intelAT&T
pop ebppopl %%ebp
mov eax, 0x11femovl $0x11FE,%%eax
call SystemCallcall SystemCall
retn 0x10retn $0x10
SystemCall:SystemCall:
mov edx, espmovl %%esp,%%edx
_emit 0x0f?
_emit 0x34?
ещё вот здесь небольшая статья
1
WinstonCherchil
7 / 7 / 2
Регистрация: 20.01.2011
Сообщений: 73
19.11.2014, 13:20  [ТС] #3
Цитата Сообщение от Mikl___ Посмотреть сообщение
попытайся переводить по одной строке, основное различие - это обратный порядок операндов и указание типа операндов в названии операции, то есть sub edx, 16 = subl $16,%edx точность не гарантирую но по моему так
Уже пытался, по томуже посту на сайбере. Не собирается, пишет:
C++
1
:-1: error: [debug/tscriptsystem.o] Error 1
Компилятор MinGW в QTCreator'e
Еще не понятно, что делать с этими _эмитами.

Может это можно как-то на С++ переписать? Мне ведь этот код еще поддерживать придется. На сколько я понял он как-то сохраняет входные параметры, вызывает функцию системную и скармливает ей эти параметры, потом возвращается. Как мне в С++ вызвать эту 0x11FE функцию?
0
Mikl___
Автор FAQ
11730 / 6042 / 543
Регистрация: 11.11.2010
Сообщений: 11,025
19.11.2014, 14:01 #4
WinstonCherchil,
0F34 это машинный код команды sysenter попробуй просто указать команду, может быть MinGW поймет

а что должен делать этот фрагмент? вызвать NtUserPostMessage из win32k.sys ? А почему нельзя просто использовать PostMessage ?
0
WinstonCherchil
7 / 7 / 2
Регистрация: 20.01.2011
Сообщений: 73
19.11.2014, 20:51  [ТС] #5
Нативки быстрее. Это часть скриптого языка типа АутоИТ. В больших приложениях лагает, а в некоторых вообще не работает.

Вот что на данный момент имею:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
int  NtUserPostMes(HWND hWnd, unsigned int Msg, WPARAM wParam, LPARAM lParam)
{
 
    __asm__ (
    "popl %%ebp"
    "movl $0x11FE,%%eax"
    "call SystemCall"
        "retn $0x10"
        "SystemCall:"
    "movl %%esp,%%edx"
    "0x0F34"
    );
}
Добавлено через 1 час 13 минут
Оригинал на Дельфи
Delphi
1
2
3
4
5
6
7
8
9
10
function NtUserPostMessage(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): BOOL; stdcall;
asm
pop ebp
mov eax, $11DB
call @SystemCall
ret $10
@SystemCall:
mov edx, esp
sysenter
end;
$11DB для старых виндоусов

Добавлено через 5 часов 14 минут
Собралось.

C++
1
2
3
4
5
6
7
    __asm("popl %ebp\n");
    __asm("movl $0x11FE, %eax\n");
    __asm("call SystemCall\n");
    __asm("ret $0x10\n");
    __asm("SystemCall:\n");
    __asm("movl %esp,%edx\n");
    __asm("sysenter");
Доходит до sysenter и вылетает с SIGILL.
0
Mikl___
Автор FAQ
11730 / 6042 / 543
Регистрация: 11.11.2010
Сообщений: 11,025
20.11.2014, 03:43 #6
WinstonCherchil,
а что за расшифровка ошибки "SIGILL" ? sysenter вызывает нативные функции в зависимости от параметра в ЕАХ, может быть для твоей Винды для вызова NtUserPostMessage нужно другое число, не 0x11FE ? и насколько быстрее работают нативные функции по сравнению с функциями вызываемыми из юзер моды? Я же не знаю СМЫСЛА ускорения твоей программы...
0
WinstonCherchil
7 / 7 / 2
Регистрация: 20.01.2011
Сообщений: 73
20.11.2014, 14:35  [ТС] #7
Там не только ускорение, таким методом можно собирать инфу о скрытых процессах (ну не PostMessage'ом, а соответствующими функциями), которые обычные АПИ не видят, и еще много прикольных вещей. В данной ситуации PostMessage взят лишь потому что легко проверить работоспособность кода - сразу видишь реакцию программы. Ну конечно его потом оставят таким, раз уж его сделали.

Что касается SIGILL - Signal Illegal instruction. Гугл говорит что на семерке х64 больше нет сисэнтера. Вместо этого предложил использовать это:
Assembler
1
2
3
4
5
6
7
_emit 0x64
_emit 0xFF
_emit 0x15
_emit 0xC0
_emit 0x00
_emit 0x00
_emit 0x00
Пытаюсь перевести это на AT&T
0
sh2ezo
1126 / 260 / 9
Регистрация: 11.06.2010
Сообщений: 1,050
25.11.2014, 19:19 #8
Ну, если доверять Hiew32, манам и коду выше, то на асм для x86 это будет:
Assembler
1
call dword [fs:0xC0]
на сях, наверное, будет как-то так:
C++
1
2
void (*f)(void) = (void (*)(void))0xC0;
f();
но что-то мне подсказывает, что с этим кодом вы будете посланы виндой
1
WinstonCherchil
7 / 7 / 2
Регистрация: 20.01.2011
Сообщений: 73
27.11.2014, 19:47  [ТС] #9
Цитата Сообщение от sh2ezo Посмотреть сообщение
call dword [fs:0xC0]
Уже сам докатился. В тему никто не писал долго, вот и перестал проверять, но спасибо.
Сейчас с другим проблема. На гуглив всякой всяины пришел к этому (я перешел на студию потому что все гуглится под нее, для МинГВа почти ничего нет.)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
bool __stdcall NtUserPostMes(HWND hWnd, unsigned int Msg, WPARAM wParam, LPARAM lParam)
{   
    //11fe: 99d979e6 NtUserPostMessage [4] (win32k.sys)
    __asm{
        mov    eax, 0x11fe
        xor    ecx, ecx
        lea    edx, [esp + 0x04]
        call   fs : [0xC0]          
        add    esp, 0x04
        retn 0x002C
    } 
 
}
Код собирается, но во время выполнения выдает ошибку
Цитата Сообщение от Microsoft Visual Studio Express 2013
Unhandled exception at 0x77077215 (ntdll.dll) in NtTests.exe: 0xC0000409: The system detected an overrun of a stack-based buffer in this application. This overrun could potentially allow a malicious user to gain control of this application.

First-chance exception at 0x77077228 (ntdll.dll) in NtTests.exe: 0xC0000005: Access violation writing location 0x770ACE80.
Unhandled exception at 0x7331C9F1 in NtTests.exe: 0xC0000005: Access violation (parameters: 0x00000008).

Unhandled exception at 0x7331C9F1 in NtTests.exe: 0xC0000005: Access violation (parameters: 0x00000008).

Unhandled exception at 0x7331C9F1 in NtTests.exe: 0xC0000005: Access violation (parameters: 0x00000008).
Взял книгу по ассемблеру, разбираюсь. Гугл сказал что в ретурне ошибся. Действительно, если подставить туда retn 0x0024 то ошибка доступа записи сменится на ошибку доступа выполнения:
Цитата Сообщение от Microsoft Visual Studio Express 2013
First-chance exception at 0x76EED7D8 in NtTests.exe: 0xC0000002: The requested operation is not implemented.
First-chance exception at 0x00000000 in NtTests.exe: 0xC0000005: Access violation executing location 0x00000000.
Unhandled exception at 0x7331C9F1 in NtTests.exe: 0xC0000005: Access violation executing location 0x00000000.
Был бы очень признателен если бы кто-то объяснил как мне вычислять все эти смещения и операнды для ret (да и просто показал бы на все ошибки), потому что самостоятельно я в этом еще пару недель разбираться буду

Добавлено через 7 минут
За основу кода брал примеры из этой статьи.

Добавлено через 2 минуты

Не по теме:

П.С. За что Mikl'а то забанили?

0
maxillion
273 / 183 / 52
Регистрация: 25.12.2012
Сообщений: 616
27.11.2014, 20:24 #10
Цитата Сообщение от WinstonCherchil Посмотреть сообщение
Гугл говорит что на семерке х64 больше нет сисэнтера
Для wow64 нет, а для x64 есть syscall.
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
;
;    extern "C" NTSTATUS  ApiCallNtService(ULONG id, ...);
;
ApiCallNtService    PROC
        mov        rax, rcx
        mov        r10, rdx        
        mov        rdx, r8
        mov        r8, r9
        mov        r9, [rsp+28h]
        add        rsp, 8
        syscall                
        sub        rsp, 8
        ret
ApiCallNtService    ENDP
Для wow64
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#define SYSCALL(id,retN)    __asm { \
        __asm mov     eax, id       \
        __asm xor     ecx, ecx      \
        __asm lea     edx, [esp+4]  \
        __asm cmp     fs:[0xC0],0   \
        __asm jnz     $+11          \
        __asm int     0x2E          \
        __asm retn    retN          \
        __asm push    ebp           \
        __asm mov     ebp, esp      \
        __asm call    fs:[0xC0]     \
        __asm mov     esp, ebp      \
        __asm pop     ebp           \
        __asm retn    retN          \
        }
Добавлено через 7 минут
А также x86.
1
WinstonCherchil
7 / 7 / 2
Регистрация: 20.01.2011
Сообщений: 73
28.11.2014, 15:15  [ТС] #11
Спасибо.

В id, я так понял я подставляю номер своей функции, в данном случае 0x11fe. А retN как вычислять?
0
maxillion
273 / 183 / 52
Регистрация: 25.12.2012
Сообщений: 616
28.11.2014, 15:36 #12
Цитата Сообщение от WinstonCherchil Посмотреть сообщение
А retN как вычислять?
Это значение служит для очистки стэка после вызова, и зависит от количества переданных аргументов в функцию.

Добавлено через 9 минут
Кстати здесь у вас ошибочка
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
bool __stdcall NtUserPostMes(HWND hWnd, unsigned int Msg, WPARAM wParam, LPARAM lParam)
{   
    //11fe: 99d979e6 NtUserPostMessage [4] (win32k.sys)
    __asm{
        mov    eax, 0x11fe
        xor    ecx, ecx
        lea    edx, [esp + 0x04]
        call   fs : [0xC0]          
        add    esp, 0x04
        retn 0x002C
    } 
 
}
0x002C уж больно много для NtUserPostMes.

Добавлено через 1 минуту
Это наверно для NtCreateFile .
1
WinstonCherchil
7 / 7 / 2
Регистрация: 20.01.2011
Сообщений: 73
28.11.2014, 16:09  [ТС] #13
В байтах? Попробовал сам посчитать - 3 указателя по 64 бита и 32 юинт = 0xE0, так же попробовал то что в примере (и еще пару других). Тоже не заработало.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
bool __stdcall NtUserPostMes(HWND hWnd, unsigned int Msg, WPARAM wParam, LPARAM lParam)
{   
    //11fe: 99d979e6 NtUserPostMessage [4] (win32k.sys)
    __asm{
        mov     eax, 0x11fe
        xor     ecx, ecx
        lea     edx, [esp + 4]
        cmp     fs : [0xC0], 0
        jnz     $ + 11
        int     0x2E
        retn    0x2C             
        push    ebp           
        mov     ebp, esp      
        call    fs : [0xC0]     
        mov     esp, ebp      
        pop     ebp           
        retn    0x2C            
        
    }
      
    
}
Получаю Acces Violation. Однако, если использовать просто ret, то получаю что-то новенькое:
Цитата Сообщение от Microsoft Visual Studio Express 2013
First-chance exception at 0x00221141 in NtTests.exe: 0xC0000096: Privileged instruction.
Unhandled exception at 0x00221141 in NtTests.exe: 0xC0000096: Privileged instruction.
0
maxillion
273 / 183 / 52
Регистрация: 25.12.2012
Сообщений: 616
28.11.2014, 16:19 #14
Кх, кх а вы уверены что правильно передали параметры ? И как они расположены в стэке вы знаете ?
Для начала надо в заголовок функции добавить naked.
C++
1
__declspec(naked) bool __stdcall NtUserPostMes(HWND hWnd, unsigned int Msg, WPARAM wParam, LPARAM lParam)
1
WinstonCherchil
7 / 7 / 2
Регистрация: 20.01.2011
Сообщений: 73
28.11.2014, 16:20  [ТС] #15
Цитата Сообщение от maxillion Посмотреть сообщение
Это наверно для NtCreateFile .
А! Понял. NtCreateFile принимает 11 параметров по 32 бита = 2Сh => по аналогии для NtUserPostMessage [4] получаем (32/8) байт * 4 параметра = 16 = 0x10. Тоже пробовал не работает.
0
maxillion
273 / 183 / 52
Регистрация: 25.12.2012
Сообщений: 616
28.11.2014, 16:24 #16
Я выше написал что вы не контролируете стэк. Запустите debbuger и смотрите что и как передаёте. Скорей всего ошибка в передаче аргументов.
1
WinstonCherchil
7 / 7 / 2
Регистрация: 20.01.2011
Сообщений: 73
28.11.2014, 16:29  [ТС] #17
__declspec(naked) bool __stdcall
Цитата Сообщение от Microsoft Visual Studio Express 2013
error C2488: 'NtUserPostMes' : 'naked' can only be applied to non-member function definitions D:\C++\NtUserFunctionsOverload\ConsoleApplication2\ConsoleApplication2.cpp
Member function? Классов нет никаких. Весь код этомейн, где тестится и эта функция с прототипом.

Добавлено через 4 минуты
Цитата Сообщение от maxillion Посмотреть сообщение
Запустите debbuger и смотрите что и как передаёте.
Студия 2013 умеет это, или придется качать отдельную программу?
0
maxillion
273 / 183 / 52
Регистрация: 25.12.2012
Сообщений: 616
28.11.2014, 16:32 #18
Не знаю как 2013 но в 2008 alt+8. Или скачайте debugger например OllyDbg - простой и мощный.
1
WinstonCherchil
7 / 7 / 2
Регистрация: 20.01.2011
Сообщений: 73
28.11.2014, 16:33  [ТС] #19
Цитата Сообщение от WinstonCherchil Посмотреть сообщение
Member function? Классов нет никаких. Весь код этомейн, где тестится и эта функция с прототипом.
Поспешил. Убрал у прототипа - все собралось и заработало. Однако кнопка так и не долетает до Калькулятора. По всей видимости, там в стеке действительно каша. Пошел гуглить.
0
maxillion
273 / 183 / 52
Регистрация: 25.12.2012
Сообщений: 616
28.11.2014, 17:15 #20
Вот рабочий вариант проверял windows 8.1.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// syscall.cpp: определяет точку входа для консольного приложения.
//
 
#include "stdafx.h"
#include <Windows.h>
 
#define SYSCALL(id,retN)    __asm { \
    __asm mov     eax, id       \
    __asm xor     ecx, ecx      \
    __asm lea     edx, [esp + 4]  \
    __asm cmp     fs : [0xC0], 0   \
    __asm jnz     $ + 11          \
    __asm int     0x2E          \
    __asm retn    retN          \
    __asm call    fs : [0xC0]     \
    __asm retn    retN          \
        }
 
__declspec(naked) void  __stdcall NtUserPostMes(HWND hWnd, unsigned int Msg, WPARAM wParam, LPARAM lParam)
{
    SYSCALL(0x1011, 0x10)
}
 
int _tmain(int argc, _TCHAR* argv[])
{
    //__asm int 3
    HWND h = (HWND)0x001204DE;
    //PostMessage(h, WM_LBUTTONDOWN, MK_LBUTTON, 0);
    //PostMessage(h, WM_LBUTTONUP, MK_LBUTTON, 0);
 
    NtUserPostMes(h, WM_LBUTTONDOWN, MK_LBUTTON, 0);
    NtUserPostMes(h, WM_LBUTTONUP, MK_LBUTTON, 0);
 
    return 0; 
}
1
28.11.2014, 17:15
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.11.2014, 17:15

Не работает ассемблерная вставка Masm32 в C++
Добрый вечер мы в институте учим ассемблерные вставки. Я пользуюсь Visual...

Ассемблерная вставка работает неправильно
Имеется такой код: #include &lt;conio.h&gt; // Для работы с функцией _getch()...

Ассемблерная вставка. Деление со знаком
На консоль выводит непонятно что - 8.40779e-045 float res; _asm{ mov...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru