• Познакомьтесь с пентестом веб-приложений на практике в нашем новом бесплатном курсе

    «Анализ защищенности веб-приложений»

    🔥 Записаться бесплатно!

  • CTF с учебными материалами Codeby Games

    Обучение кибербезопасности в игровой форме. Более 200 заданий по Active Directory, OSINT, PWN, Веб, Стеганографии, Реверс-инжинирингу, Форензике и Криптографии. Школа CTF с бесплатными курсами по всем категориям.

Что-то не в порядке с Directdraw...

  • Автор темы Guest
  • Дата начала
G

Guest

Читал на сайте cyberguru.ru "Получение прямого доступа к видеопамяти средствами DirectDraw", списал оттуда весь код, но он не работает (а именно, не хочет создавать поверхность). Вот код программы:
C++:
#include "stdafx.h"
#include <ddraw.h>
#pragma comment (lib, "ddraw.lib")

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR	 lpCmdLine,
int	  nCmdShow)
{
IDirectDraw *dd;
HRESULT hdr = DirectDrawCreate (NULL, &dd, NULL);
dd->SetCooperativeLevel (NULL, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
dd->SetDisplayMode (800, 600, 8);
DDSURFACEDESC desc;
ZeroMemory (&desc, sizeof (DDSURFACEDESC));
desc.dwSize = sizeof (DDSURFACEDESC);
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
desc.dwFlags = DDSD_CAPS;
IDirectDrawSurface *sf;
HRESULT hr = dd->CreateSurface (&desc, &sf, NULL);
if (hr != DD_OK)
MessageBox (0, "Error CreateSurface!", 0, 0);
sf->Lock (NULL, &desc, DDLOCK_WAIT, NULL);
sf->Unlock (desc.lpSurface);
Sleep (1000);
dd->Release ();
return 0;
}
Программа выводит MessageBox и висит. Не знаю, что делать. Помогите, если кто-то знает!
 
D

DarkKnight

Тут мое мнение проблема только в том, что ты не создаешь главное окно и не регистрируешь его класс....
Но я могу правда и ошибаться, может при прямом доступе к видеопамяти (даже в Win) и не обязательно создавать окно, но я бы точно бы создал....
WNDCLASSEX Okno; //и пошел
...
..
.
//Класс, регстрция класса, создания окна класса, обработчик событий... Ну и твой код... И бесконечный цикл обаботки MSG Win...
Ну опять же говорю, что я могу и ошибаться, могу только тоно сказать, что DirectDraw - должен работать на сабзе Win-Application (из этого могу предположить, что должно быть хотя бы окно)
 
M

mibin

А вообще где ты определяешь сам директ икс? Помоему если я все правильно помню..сначало нужно определить то что ты работаешь с директоиксом каким а дирет дро это часть него уже
 
D

DarkKnight

Не, определено у него все правельно...
Хедер указан, lib присоединен... Так что доступ к DirectDraw он точно получает...
 
M

mibin

Попробуй создать с помощью DirectDrawCreateEx...
и добавь обработчик события на создание и на установку уровня взаимодействия, может интерфейс проблема раньше возникла
 
D

DarkKnight

Не, я проверял, этот участок кода у него точно работает, так как разрешение меняется и реально эксклюзив-доступ есть... А вот поверхность не хочет... Все равно думаю что оконное приложение должно быть... Лень проверить пока что...

IDirectDraw *dd;
HRESULT hdr = DirectDrawCreate (NULL, &dd, NULL);
dd->SetCooperativeLevel (NULL, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
dd->SetDisplayMode (800, 600, 8);
DDSURFACEDESC desc;
 
G

Guest

Тут мое мнение проблема только в том, что ты не создаешь главное окно и не регистрируешь его класс....
Вы были, как всегда, правы. Только есть одно 'но':
WNDCLASSEX Okno; //и пошел
Можно и просто WNDCLASS. А вот функция GetForegroundWindow () подойдёт?
На дату прошу не смотреть, так как я был занят совсем другим и мне было просто не до кодебая.
 
G

Guest

Что-то на мой вопрос долго не приходит ответ. У меня возник ещё один вопрос: если у меня 24-разрядный формат пикселя - как мне создать тип данных размером в 3 байта???
 
G

Guest

L

lazybiz

А не структуру вряд ли получится.
Получится.

P. S. А зачем вообще писать typedef struct { ... } color; если можно struct color { ... };???
Для того, чтобы определить color как тип а не как переменную. Тебе же именно тип нужен был.
 
L

lazybiz

А не структуру вряд ли получится.
Сформулируй вопрос понятным образом, а то я могу не совсем точно понять о чем ты спрашиваешь.
С ходу я понял что структура, как ты думаешь, не подойдет для этого случая. Правильно я понял?

Но я же сказал - struct color { ... }; Это же тоже создаёт тип.
Это по-сути одно и то же. Просто я привык к такому синтаксису.
 
L

lazybiz

Партизан
Кстати, если использовать 4-х байтовый тип данных, то скорость записи в память возрастет; А если же ты будешь писать в 8-битном режиме то я могу тебе описать самый быстрый (какой только возможен на С) вариант.
 
G

Guest

С ходу я понял что структура, как ты думаешь, не подойдет для этого случая. Правильно я понял?
Это не так важно, просто мне интересно. Я говорю про что-то вроде этого:
C++:
typedef XXX color; // Размер XXX - 3 байта. Это не класс и не структура.
Я могу тебе описать самый быстрый (какой только возможен на С) вариант.
И что это за вариант? Опишите, пожалуйста.
 
L

lazybiz

И что это за вариант? Опишите, пожалуйста.
Этот случай актуален только при записи в 8-битном режиме, т.е. если тебя интересует 8-битный режим.

Суть в том, чтобы писать не байтами, а двойными словами (т.е. четырехбайтными порциями), при чем выровненными по границе, кратной 4-ке. Этот способ дает очень хороший результат при правильном применении. Его так же можно использовать при заполнении памяти определенным значением (как memset() в Си), и работать это будет очень быстро.

Вот пример из заполнения строки при рисовании треугольника (взято из старых примеров Watcom C++):

C++:
void fill( BYTE *p, int x0, int x1, DWORD c )
{
int dx, z;
dx = x1 - x0 + 1;
p += x0;
if ( dx > 4 ) {
if ( z = (DWORD)p & 3 ) {
while ( z++ < 4 ) {
*p++ = (BYTE)c;
dx--;
}
}
while ( dx >= 4 ) {
*((DWORD *)p) = c;
p += 4;
dx -= 4;
}
}
while ( dx-- > 0 ) *p++ = (BYTE)c;
}
 
G

Guest

Вот пример из заполнения строки при рисовании треугольника.
Не совсем понятно, как он работает. Что значат аргументы x0 и x1? Что значат локальные переменные dx и z? Без комментариев и понятных названий, как видите, разобрать ничего невозможно и даже одна функция превращается в кучу непонятного кода.
 
L

lazybiz

Вот тебе наглядный пример работы. Если тебе и тут не совсем понятно, то уж извини.
C++:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <mem.h>

//
// sizeof( u8 ) == 1
// sizeof( u32 ) == 4
//
typedef unsigned char		u8;
typedef unsigned long		u32;

#define	TEST_SIZE			(1024 * 1024 * 8)
#define	TEST_VALUE			123
#define	TEST_ITERATIONS		500

void fill_asm( u8 *, u8, u32 );
#pragma aux fill_asm =						\
"		mov		ah, al					"	\
"		shl		eax, 8					"	\
"		mov		al, ah					"	\
"		shl		eax, 8					"	\
"		mov		al, ah					"	\
"		lea		ecx, [edi + edi * 2]	"	\
"		and		ecx, 3					"	\
"		sub		esi, ecx				"	\
"		jle		short leb				"	\
"		rep		stosb					"	\
"		mov		ecx, esi				"	\
"		and		esi, 3					"	\
"		shr		ecx, 2					"	\
"		rep		stosd					"	\
"leb:	add		ecx, esi				"	\
"		rep		stosb					"	\
parm	[edi] [al] [esi]			\
modify exact [eax ecx esi edi];

void fill_c( u8 *p, u8 v, u32 n )
{
u32	z, c;
c = v;
c |= c << 8;
c |= c << 16;
if ( n > 4 ) {
if ( z = (u32)p & 3 ) {
while ( z++ < 4 ) {
*p++ = (u8)c;
n--;
}
}
while ( n >= 4 ) {
*((u32 *)p) = c;
p += 4;
n -= 4;
}
}
while ( n-- > 0 ) *p++ = (u8)c;
}

void main()
{
int		i, j, k;
DWORD	time;
u8 *	p;

p = (u8 *)malloc( TEST_SIZE );
if ( !p ) {
printf( "malloc( %d ) failed.\n", TEST_SIZE );
return;
}

printf( "wait 3 seconds...\n" );
Sleep( 3000 );


memset( p, TEST_VALUE, TEST_SIZE );
fill_c( p, TEST_VALUE, TEST_SIZE );
fill_asm( p, TEST_VALUE, TEST_SIZE );

for ( k = 0; k < 8; k++ ) {
printf( "\nbuffer size: %d, iterations: %d\n", TEST_SIZE >> k, TEST_ITERATIONS );


printf( "memset(): " );
time = timeGetTime();
for ( j = 0; j < 10; j++ ) {
for ( i = 0; i < TEST_ITERATIONS; i++ ) {
memset( p + j, TEST_VALUE, (TEST_SIZE >> k) - j );
}
}
time = timeGetTime() - time;
printf( "%5.2f seconds\n", (double)time / 1000.0 );


printf( "fill_c(): " );
time = timeGetTime();
for ( j = 0; j < 10; j++ ) {
for ( i = 0; i < TEST_ITERATIONS; i++ ) {
fill_c( p + j, TEST_VALUE, (TEST_SIZE >> k) - j );
}
}
time = timeGetTime() - time;
printf( "%5.2f seconds\n", (double)time / 1000.0 );


printf( "fill_asm(): " );
time = timeGetTime();
for ( j = 0; j < 10; j++ ) {
for ( i = 0; i < TEST_ITERATIONS; i++ ) {
fill_asm( p + j, TEST_VALUE, (TEST_SIZE >> k) - j );
}
}
time = timeGetTime() - time;
printf( "%5.2f seconds\n", (double)time / 1000.0 );
}

free( p );
}

Результат у меня выдал такой:
 

Вложения

  • fill_test.png
    fill_test.png
    32,1 КБ · Просмотры: 465
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!