Ассемблер Для Начинающих
Author: Horrible • 2005-05-16T16:03:20+0000 • Replies: 170 • Views: 65K
Я тут подумал, что неплохобылоб изучать асму. И захотелось посмотреть
какойнить простой пример. Как на ассемблере нерисовать мессаджбокс (только не
через winapi)?  
  
Попутно вопрос: может кто поделится личным опытом. С чего начать изучение,
какой компилятор/линкер выбрать и т.п. Вобщем все по теме Асм для зелёных.  
  
Зашол на wasm.ru и ненашол там никаких статей для новичков. Может плохо искал?  
  
[mod] Great: Тут задаем все вопросы по асму. Другие топики аналогичного
содержания будут удаляться[/mod]
Выбор языка программирования в 2020 году
Author: jifila • 2019-06-23T09:35:31+0000 • Replies: 27 • Views: 17K
Для веба выбираю между пхп + хтмл + ксс + жкьюри (все это во фреймворке
бутстрап 4.3.1) и просто пхп + хтмл + ксс (без фреймворков) для небольших
минималистичных проектов с полной прозрачностью (бекдоры в скриптах на сайте
никому не нужны).  
Для софта выбираю между си или асмом. Последнее особенно интересует из-за
уникальности и олдскульности.  
  
Первое нужно для крупных коммерческих проектов с серьезным бюджетом, трафиком
и небольших проектов "для своих", где важно полное доверие к сайту, сервису.  
Второе нужно для ядр ос, автоматизации, защитных и изоляционных программ. То
есть, работа будет на максимально низком - "железном" уровне.  
  
Встречал инфу о поднятии сайтов на сиплюсах, пайтоне, чистом жкьюри, как они
это организовывают? И есть ли в таком смысл?
FASM manual (на русском языке) [PDF edition]
Author: Namelles One • 2009-06-30T11:16:10+0000 • Replies: 5 • Views: 12K
Как вам всем известно - существует русский перевод классического FASM
manual-а, выполненный Paranoik-ом. Но, по причине того, что сверстан этот
перевод был в виде двух txt файлов - читать, а уж тем более печатать эти
документы было адски сложно, а результат был абсолютно непрезентабельным.  
  
Маясь от скуки во время жуткой жары, когда программировать организм
отказывался и работали лишь простейшие двигательные рефлексы, я решил
исправить ситуацию.  
  
Текст из обоих файлов был загружен в TexMaker, далее была выполнена полная
разметка LaTeX (абзацы, исходники, таблицы) и получен pdf файл, прикрепленный
к данному сообщению. Также были исправлены все найденные опечатки.  
  
Прошу в этой теме сообщать о всех неточностях и косяках - изменения
воспоследуют.
Книги по основам программирования
Author: Quake3 • 2019-04-22T16:12:46+0000 • Replies: 17 • Views: 11K
Существует огромное количество книг (а также статей, видеокурсов и подобного)
по основам программирования. Огромное, потому что гораздо легче написать
материал вида "пишем хелловорлд", чем что-то специфическое , да и спрос на
литературу для новичков гораздо выше. Среди всего этого добра мне попались
книги одного автора, который начинает не из популярных яваскриптов и питонов,
а из самых "низов" \- изучения устройства операционной системы, ассемблера,
Си, основы сетей. В общем, вот эти книги  
  
_<http://www.stolyarov.info/books/programming_intro> , там 3 файла в формате
PDF  
  
Автор довольно таки специфический человек (о его личности можно почитать в
коментах на сайте или на том же ЛОРе), к примеру он ненавидит яваскрипт,
негативно относится к стандартам Си/С++ (после 98 года), но все же, книги
хорошие, и заслуживают внимания.
какой язык программирования выбрать для быстрых денег в России ?
Author: asdfghgov • 2022-11-14T15:23:54+0000 • Replies: 73 • Views: 11K
Нет опыта в программировании, думаю что выбрать для начала карьеры в IT.
JavaScript (Node.JS) или Go-Lang.
zennopster
Author: kali • 2019-11-20T10:15:52+0000 • Replies: 23 • Views: 10K
мне в руки попал очень иинтерресный шабллон на зеннопостер ,и так как у меня
никогда не было лицензии,а купить  
чтобы потестить один шаблон както ...  
Где можно заполучить кряк?быть может кто-то когда купил это чудо и оно теперь
занимает место на жеском)  
я готов его забрать и отправить вам на пиво\мороженое что пожилаете)
Autoit исходники
Author: timbo • 2019-12-08T13:09:49+0000 • Replies: 27 • Views: 9K
Junk Code Generator  
  
[CLIKE]  
Code:Copy to clipboard
    
    
    ;START OF CONFIG
    $target = 1000            ;number of lines
    $file = "junk.txt"        ;file to store in
    $numlines = 10            ;number of temporary lines, 10 works p good
    ;END OF CONFIG
    
    FileDelete($file) ;just in case it exists already, we don't want to waste our time!
    
    Dim $lines[$numlines + 1] ;first we create the array
    $lines[0] = $numlines ;this isn't really needed but i love my arrays like that.
    _dimlines($numlines) ;dim the temporary lines for the first time
    FileWrite($file, "") ;create the file
    $i = 0 ;set an int to count our loop / the lines created
    $stept = Random(20,30,1) ;after this the lines will get redimed in order to leave no pattern
    Do ;start of a do loop
        If $i = $stept Then ;With this we count to the next redim
            $stept = $stept + Random($i + 20, $i + 30,1) ;and if it happens we set a new point for it (p random to leave no pattern again)
            _dimlines($numlines) ;and redim all lines
        EndIf ;End of that part!
        $i = $i + 1 ;line count variable + 1
        $rand = Random(1,10,1) ; create a random number
        FileWriteLine($file, $lines[$rand]) ;and write one of the the temp lines to the file
        $per = $i / $target * 100 ;calculate the %
        ToolTip($i & "/" & $target & " lines created - That's " & $per & "%");and display a nice message for the user
    Until $i = $target ;we do that until we reached the number of lines we want
    
    Func _dimlines($dtarget) ;this is the func to dim/redim the the lines
    $d = 1 ;a new int for the loop below
    Do ;a do loop again :o
        $lines[$d] =  "$" & Random(50000,150000,1) & ' = "' & Random(50000,150000,1) & '"' ;That is how a line gets generate only 2 random numbers + the operators
        $d = $d + 1 ;$d++
    Until $d = $dtarget ;the loop does it for any temp line
    EndFunc ;end of the func
[/CLIKE]
Генерация чисел
Author: Left4Dead • 2013-01-25T21:22:11+0000 • Replies: 27 • Views: 8K
Spoiler: 100
У крипторов и всякой разной малвары часто стоят задачи обфускации строк, хеш-
таблиц для поиска API, выплёвывания EXE, шеллкода или генерация ключа
шифрования.  
Самый примитивный вариант это иметь зашифрованные данные в секции данных или
ресурсах, ключ шифрования и код для расшифровки этого дела. Но нехорошо
получается, когда например закриптованный файл состоит из небольшой секции
кода, которая является расшифровщиком, и здоровой секции данных, которая
содержит трой.  
А если генерировать данные программно, т.е. алгоритмически, то можно обойтись
вообще без секции данных. Либо частично генерировать данные программно, чтобы
сократить размер секции данных и привести соотношение размеров секций
кода/данных к нормальному.  
В общем случае все эти задачи сводятся к генерации чисел, т.к. любые данные и
код можно представить в виде набора байт.  
  
Раньше я делал это так: предварительно "шифруем" исходные данные путём
вычисления некой обратимой функции типа тангенс от каждого байта исходных
данных. Потом рабочий код вычисляет обратную функцию арктангенс от
"зашифрованных" байт, при чем вызывая не какие-то математические библиотечные
функции, а делает это с помощью циклического подсчёта значения разложения
функции арктангенс в ряд Тейлора.  
В этом способе мне не нравится недостаточная запутанность и данные хоть и не
увеличивают секцию данных, но фактически в явном виде содержатся в командах
типа mov eax, 12345h, что весьма некошерно как по мне.  
Поэтому я разработал генератор чисел без использования данных вообще. По сути
на вход только надо подать любое заранее известное число, например значение
возвращаемое какой-нибудь антиэмуляционной API-функцией.  
  
Суть алгоритма: работать будем с 1-байтовыми значениями, генерировать будем
формулы. Формула это дерево, вершина которого может быть 3 видов: унарная
операция, бинарная операция, операнд. Далее формула-дерево транслируется в
С-код.  
Задача состоит в том, чтобы сгененировать формулу которая преобразует заданное
число X в Y. Таким образом код генерации любого массива будет состоять из
последовательных преобразований X -> Y1 -> Y2 -> Y3 -> Y4 ...  
Случайное дерево-формула генерируется функцией struct tree*
create_random_tree( unsigned int depth )  
значение формулы подсчитывается функцией unsigned char count_tree( struct
tree* t, unsigned char operand_value )  
дерево-формула транслируется в C-код функцией char* tree_to_string( struct
tree* t, char* operand )  
функция struct tree* generate_tree( unsigned char x, unsigned char y )
генерирует случайные деревья-формулы, пока при подстановке X в качестве
значения операнда не получится Y.  
  
Proof-of-concept:  
  
Code:Copy to clipboard
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define TREE_NODE_OPERAND	0
    #define TREE_NODE_UNARY  1
    #define TREE_NODE_BINARY	2
    
    #define TREE_MAX_DEPTH  8
    
    struct tree
    {
    	char type, opcode;
    	struct tree *child_left, *child_right;
    };
    
    unsigned char *unary_array;
    unsigned char *binary_array;
    
    unsigned char calculate_unary( unsigned char a, unsigned char opcode )
    {
    	switch ( opcode )
    	{
      case 0x00: return (unsigned char) ( a );
      case 0x01: return (unsigned char) ( ~( (unsigned char)a ) );
      case 0x02: return (unsigned char) ( (unsigned char)a + 1);
      case 0x03: return (unsigned char) ( (unsigned char)a - 1);
      case 0x04: return (unsigned char) ( (unsigned char)a >> 1 );
      case 0x05: return (unsigned char) ( (unsigned char)a >> 2 );
      case 0x06: return (unsigned char) ( (unsigned char)a >> 3 );
      case 0x07: return (unsigned char) ( (unsigned char)a >> 4 );
      case 0x08: return (unsigned char) ( (unsigned char)a << 1 );
      case 0x09: return (unsigned char) ( (unsigned char)a << 2 );
      case 0x0A: return (unsigned char) ( (unsigned char)a << 3 );
      case 0x0B: return (unsigned char) ( (unsigned char)a << 4 );
    	}	
    }
    
    char* unary_to_string( char *operand, char opcode )
    {
    	char* result = malloc( strlen( operand ) + 128 );
    	switch ( opcode )
    	{
      case 0x00: sprintf( result, "(unsigned char)( %s )", operand ); break;
      case 0x01: sprintf( result, "(unsigned char)( ~( (unsigned char)%s ) )", operand ); break;
      case 0x02: sprintf( result, "(unsigned char)( (unsigned char)%s + 1 )", operand ); break;
      case 0x03: sprintf( result, "(unsigned char)( (unsigned char)%s - 1 )", operand ); break;
      case 0x04: sprintf( result, "(unsigned char)( (unsigned char)%s >> 1 )", operand ); break;
      case 0x05: sprintf( result, "(unsigned char)( (unsigned char)%s >> 2 )", operand ); break;
      case 0x06: sprintf( result, "(unsigned char)( (unsigned char)%s >> 3 )", operand ); break;
      case 0x07: sprintf( result, "(unsigned char)( (unsigned char)%s >> 4 )", operand ); break;
      case 0x08: sprintf( result, "(unsigned char)( (unsigned char)%s << 1 )", operand ); break;
      case 0x09: sprintf( result, "(unsigned char)( (unsigned char)%s << 2 )", operand ); break;
      case 0x0A: sprintf( result, "(unsigned char)( (unsigned char)%s << 3 )", operand ); break;
      case 0x0B: sprintf( result, "(unsigned char)( (unsigned char)%s << 4 )", operand ); break;
    	}	
    	return result;
    }
    
    unsigned char calculate_binary( unsigned char a, unsigned char b, unsigned char opcode )
    {
    	switch ( opcode )
    	{
      case 0x00: return (unsigned char)( (unsigned char) a & (unsigned char) b );
      case 0x01: return (unsigned char)( (unsigned char) a ^ (unsigned char) b );
      case 0x02: return (unsigned char)( (unsigned char) a | (unsigned char) b );
      case 0x03: return (unsigned char)( (unsigned char) a + (unsigned char) b );
      case 0x04: return (unsigned char)( (unsigned char) a - (unsigned char) b );
      case 0x05: return (unsigned char)( (unsigned char) a * (unsigned char) b );
    	}
    }
    
    char* binary_to_string( char *operand_left, char *operand_right, char opcode )
    {
    	char* result = malloc( strlen( operand_left ) + strlen( operand_right ) + 128 );
    	switch ( opcode )
    	{
      case 0x00: sprintf( result, "( %s & %s )", operand_left, operand_right ); break;
      case 0x01: sprintf( result, "( %s ^ %s )", operand_left, operand_right ); break;
      case 0x02: sprintf( result, "( %s | %s )", operand_left, operand_right ); break;
      case 0x03: sprintf( result, "( %s + %s )", operand_left, operand_right ); break;
      case 0x04: sprintf( result, "( %s - %s )", operand_left, operand_right ); break;
      case 0x05: sprintf( result, "( %s * %s )", operand_left, operand_right ); break;
    	}	
    	return result;
    }
    
    void precalculate_unary_array( )
    {
    	int a, opcode;
    	int sz = ( 0xFF + 1 ) * ( 0x0B + 1 );
    	
    	unary_array = ( unsigned char * ) malloc( sz );
    	
    	for ( a = 0x00; a <= 0xFF; a++ )
      for ( opcode = 0x00; opcode <= 0x0B; opcode++ )
      	unary_array[ a * ( 0x0B + 1 ) + opcode ] = calculate_unary( (unsigned char) a, (unsigned char) opcode );
    }
    
    void precalculate_binary_array( )
    {
    	int a, b, opcode;
    	int sz = ( 0xFF + 1) * ( 0xFF + 1 ) * ( 0x05 + 1);
    	
    	binary_array = ( unsigned char * ) malloc( sz );
    	
    	for ( a = 0x00; a <= 0xFF; a++ )
      for ( b = 0x00; b <= 0xFF; b++ )
      	for ( opcode = 0x00; opcode <= 0x05; opcode++ )
        binary_array[ a * ( 0xFF + 1 ) * ( 0x05 + 1 ) + b * ( 0x05 + 1 ) + opcode ] =  calculate_binary( (unsigned char) a, (unsigned char) b, (unsigned char) opcode );
    }
    
    struct tree* create_random_tree( unsigned int depth )
    {
    	struct tree* result;
    	result = (struct tree*) malloc( sizeof( struct tree ) );
    	
    	if ( depth <= 1 )
    	{
      result->type = TREE_NODE_OPERAND;
      result->child_left = NULL;
      result->child_right = NULL;
    	}
    	else
    	{
      result->type = rand( ) % 3;
      if ( result->type == TREE_NODE_UNARY )
      {
      	result->opcode = rand( ) % ( 0x0B + 1 );
      	result->child_left = create_random_tree( depth - 1 );
      	result->child_right = NULL;
      }
      else if ( result->type == TREE_NODE_BINARY )
      {
      	result->opcode = rand( ) % ( 0x05 + 1 );
      	result->child_left = create_random_tree( depth - 1 );
      	result->child_right = create_random_tree( depth - 1 );
      }
      else
      {
      	result->child_left = NULL;
      	result->child_right = NULL;  	
      }
    	}
    	
    	return result;
    }
    
    void delete_tree( struct tree* t )
    {
    	if ( t != NULL )
    	{
      if ( t->child_left != NULL )
      	delete_tree( t->child_left );
    
      if ( t->child_right != NULL )
      	delete_tree( t->child_right );
      	
      free( t );
    	}
    }
    
    unsigned char count_tree( struct tree* t, unsigned char operand_value )
    {
    	switch ( t->type )
    	{
      case TREE_NODE_OPERAND: return operand_value; 
      case TREE_NODE_UNARY:	return unary_array[ count_tree( t->child_left, operand_value ) * ( 0x0B + 1 ) + t->opcode ]; 
      case TREE_NODE_BINARY:	return binary_array[ count_tree( t->child_left, operand_value ) * ( 0xFF + 1 ) * ( 0x05 + 1 ) + count_tree( t->child_right, operand_value ) * ( 0x05 + 1 ) + t->opcode ];
    	}
    }
    
    char* tree_to_string( struct tree* t, char* operand )
    {
    	switch ( t->type )
    	{
      case TREE_NODE_OPERAND: return operand;
      case TREE_NODE_UNARY:	return unary_to_string( tree_to_string( t->child_left, operand ), t->opcode );
      case TREE_NODE_BINARY:	return binary_to_string( tree_to_string( t->child_left, operand ), tree_to_string( t->child_right, operand ), t->opcode );
    	}
    }
    
    struct tree* generate_tree( unsigned char x, unsigned char y )
    {
    	struct tree* t;
    	do 
    	{
      if ( t != NULL )
      	delete_tree( t );
      	
      t = create_random_tree( TREE_MAX_DEPTH );
    	}
    	while ( count_tree( t, x ) != y );
    	return t;
    }
    
    void main()
    {
    	struct tree* t;
    	unsigned char x, y;
    	char *st;
    	FILE *f;
    	int i;
    	
    	f = fopen( "/tmp/test.c", "w" );
    	fprintf( f, "#include <stdio.h>\nvoid main(){\n	unsigned char x, y, c;\n" );
    	
    	srand ( time(NULL) );
    	
    	precalculate_unary_array( );
    	precalculate_binary_array( );
    
    	for ( i = 0; i < 10; i++ )
    	{
      x = rand( ) % 256;
      t = create_random_tree( 3 + rand( ) % 5 );
      st = tree_to_string( t, "x" );
      y = count_tree( t, x );
      delete_tree( t );
      printf( "x = %i, y = %i\n%s\n", x, y, st );
    
      fprintf( f, "	x = %i;\n", x );
      fprintf( f, "	y = %i;\n", y );
      fprintf( f, "	c = %s;\n", st );
      fprintf( f, "	if ( c != y ) " );
      fprintf( f, "	printf( \"x = %%i, y = %%i, c = %%i\\t%s\\n\", x, y, c );\n", st );
    	}
    	
    	fprintf( f, "}\n" );
    	fclose( f );
    }
  
**Добавлено в [time]1359148931[/time]**  
Spoiler: 100
пример генерируемых формул:  
  
( ( ( ( ( ( (unsigned char)( ~( (unsigned char)x ) ) + x ) & (unsigned char)( (unsigned char)(unsigned char)( (unsigned char)x << 1 ) >> 3 ) ) | x ) & (unsigned char)( (unsigned char)(unsigned char)( (unsigned char)( (unsigned char)( (unsigned char)x - 1 ) + (unsigned char)( (unsigned char)x >> 1 ) ) >> 1 ) >> 1 ) ) - (unsigned char)( (unsigned char)( ( (unsigned char)( (unsigned char)(unsigned char)( (unsigned char)x >> 4 ) << 4 ) ^ ( ( x - x ) & (unsigned char)( (unsigned char)x + 1 ) ) ) ^ x ) >> 4 ) ) | x )  
x = 8, y = 10, count_tree = 10  
  
(unsigned char)( (unsigned char)(unsigned char)( (unsigned char)( x + x ) << 3
) >> 2 )  
x = 235, y = 44, count_tree = 44  
  
( x + ( x | (unsigned char)( (unsigned char)(unsigned char)( (unsigned char)(unsigned char)( ~( (unsigned char)x ) ) << 2 ) >> 4 ) ) )  
x = 41, y = 86, count_tree = 86
  
Spoiler:  3 у вас 43
вот что выходит в ассемблерном виде (синтаксис gas):  
  
Code:Copy to clipboard
    
    
    	.file	"test.c"
    	.section	.rodata
    .LC0:
    	.string	"x = %i, y = %i, c = %i\tx\n"
    	.align 8
    .LC1:
    	.string	"x = %i, y = %i, c = %i\t(unsigned char)( (unsigned char)( x | x ) << 3 )\n"
    	.align 8
    .LC2:
    	.string	"x = %i, y = %i, c = %i\t( ( ( x | x ) & ( x + x ) ) - ( x + ( x & x ) ) )\n"
    	.align 8
    .LC3:
    	.string	"x = %i, y = %i, c = %i\t( (unsigned char)( (unsigned char)( x + ( ( (unsigned char)( (unsigned char)x << 4 ) * (unsigned char)( (unsigned char)x << 3 ) ) * (unsigned char)( (unsigned char)( x | x ) << 1 ) ) ) << 4 ) | x )\n"
    	.align 8
    .LC4:
    	.string	"x = %i, y = %i, c = %i\t( x + ( (unsigned char)( (unsigned char)(unsigned char)( (unsigned char)x << 2 ) >> 3 ) ^ ( x - (unsigned char)( ~( (unsigned char)x ) ) ) ) )\n"
    	.align 8
    .LC5:
    	.string	"x = %i, y = %i, c = %i\t(unsigned char)( (unsigned char)x << 2 )\n"
    	.align 8
    .LC6:
    	.string	"x = %i, y = %i, c = %i\t( (unsigned char)( (unsigned char)x >> 4 ) ^ x )\n"
    	.align 8
    .LC7:
    	.string	"x = %i, y = %i, c = %i\t(unsigned char)( (unsigned char)(unsigned char)( (unsigned char)x >> 1 ) << 3 )\n"
    	.text
    	.globl	main
    	.type	main, @function
    main:
    .LFB0:
    	.cfi_startproc
    	pushq	%rbp
    	.cfi_def_cfa_offset 16
    	.cfi_offset 6, -16
    	movq	%rsp, %rbp
    	.cfi_def_cfa_register 6
    	subq	$32, %rsp
    	movb	$115, -3(%rbp)
    	movb	$115, -2(%rbp)
    	movzbl	-3(%rbp), %eax
    	movb	%al, -1(%rbp)
    	movzbl	-1(%rbp), %eax
    	cmpb	-2(%rbp), %al
    	je	.L2
    	movzbl	-1(%rbp), %ecx
    	movzbl	-2(%rbp), %edx
    	movzbl	-3(%rbp), %eax
    	movl	%eax, %esi
    	movl	$.LC0, %edi
    	movl	$0, %eax
    	call	printf
    .L2:
    	movb	$-71, -3(%rbp)
    	movb	$-56, -2(%rbp)
    	movzbl	-3(%rbp), %eax
    	sall	$3, %eax
    	movb	%al, -1(%rbp)
    	movzbl	-1(%rbp), %eax
    	cmpb	-2(%rbp), %al
    	je	.L3
    	movzbl	-1(%rbp), %ecx
    	movzbl	-2(%rbp), %edx
    	movzbl	-3(%rbp), %eax
    	movl	%eax, %esi
    	movl	$.LC1, %edi
    	movl	$0, %eax
    	call	printf
    .L3:
    	movb	$111, -3(%rbp)
    	movb	$111, -2(%rbp)
    	movzbl	-3(%rbp), %eax
    	movb	%al, -1(%rbp)
    	movzbl	-1(%rbp), %eax
    	cmpb	-2(%rbp), %al
    	je	.L4
    	movzbl	-1(%rbp), %ecx
    	movzbl	-2(%rbp), %edx
    	movzbl	-3(%rbp), %eax
    	movl	%eax, %esi
    	movl	$.LC0, %edi
    	movl	$0, %eax
    	call	printf
    .L4:
    	movb	$82, -3(%rbp)
    	movb	$92, -2(%rbp)
    	movzbl	-3(%rbp), %eax
    	addl	%eax, %eax
    	movl	%eax, %edx
    	movzbl	-3(%rbp), %eax
    	andl	%edx, %eax
    	movl	%eax, %edx
    	movzbl	-3(%rbp), %eax
    	addl	%eax, %eax
    	movl	%edx, %ecx
    	subl	%eax, %ecx
    	movl	%ecx, %eax
    	movb	%al, -1(%rbp)
    	movzbl	-1(%rbp), %eax
    	cmpb	-2(%rbp), %al
    	je	.L5
    	movzbl	-1(%rbp), %ecx
    	movzbl	-2(%rbp), %edx
    	movzbl	-3(%rbp), %eax
    	movl	%eax, %esi
    	movl	$.LC2, %edi
    	movl	$0, %eax
    	call	printf
    .L5:
    	movb	$-43, -3(%rbp)
    	movb	$-43, -2(%rbp)
    	movzbl	-3(%rbp), %eax
    	movl	%eax, %ecx
    	sall	$4, %ecx
    	movzbl	-3(%rbp), %eax
    	leal	0(,%rax,8), %edx
    	movl	%ecx, %eax
    	imull	%edx, %eax
    	movb	%al, -17(%rbp)
    	movzbl	-3(%rbp), %edx
    	addl	%edx, %edx
    	movzbl	-17(%rbp), %eax
    	imull	%edx, %eax
    	movl	%eax, %edx
    	movzbl	-3(%rbp), %eax
    	addl	%edx, %eax
    	sall	$4, %eax
    	orb	-3(%rbp), %al
    	movb	%al, -1(%rbp)
    	movzbl	-1(%rbp), %eax
    	cmpb	-2(%rbp), %al
    	je	.L6
    	movzbl	-1(%rbp), %ecx
    	movzbl	-2(%rbp), %edx
    	movzbl	-3(%rbp), %eax
    	movl	%eax, %esi
    	movl	$.LC3, %edi
    	movl	$0, %eax
    	call	printf
    .L6:
    	movb	$48, -3(%rbp)
    	movb	$-87, -2(%rbp)
    	movzbl	-3(%rbp), %eax
    	sall	$2, %eax
    	shrb	$3, %al
    	movl	%eax, %edx
    	movzbl	-3(%rbp), %eax
    	addl	%eax, %eax
    	addl	$1, %eax
    	xorl	%edx, %eax
    	movl	%eax, %edx
    	movzbl	-3(%rbp), %eax
    	addl	%edx, %eax
    	movb	%al, -1(%rbp)
    	movzbl	-1(%rbp), %eax
    	cmpb	-2(%rbp), %al
    	je	.L7
    	movzbl	-1(%rbp), %ecx
    	movzbl	-2(%rbp), %edx
    	movzbl	-3(%rbp), %eax
    	movl	%eax, %esi
    	movl	$.LC4, %edi
    	movl	$0, %eax
    	call	printf
    .L7:
    	movb	$-4, -3(%rbp)
    	movb	$-16, -2(%rbp)
    	movzbl	-3(%rbp), %eax
    	sall	$2, %eax
    	movb	%al, -1(%rbp)
    	movzbl	-1(%rbp), %eax
    	cmpb	-2(%rbp), %al
    	je	.L8
    	movzbl	-1(%rbp), %ecx
    	movzbl	-2(%rbp), %edx
    	movzbl	-3(%rbp), %eax
    	movl	%eax, %esi
    	movl	$.LC5, %edi
    	movl	$0, %eax
    	call	printf
    .L8:
    	movb	$35, -3(%rbp)
    	movb	$33, -2(%rbp)
    	movzbl	-3(%rbp), %eax
    	shrb	$4, %al
    	xorb	-3(%rbp), %al
    	movb	%al, -1(%rbp)
    	movzbl	-1(%rbp), %eax
    	cmpb	-2(%rbp), %al
    	je	.L9
    	movzbl	-1(%rbp), %ecx
    	movzbl	-2(%rbp), %edx
    	movzbl	-3(%rbp), %eax
    	movl	%eax, %esi
    	movl	$.LC6, %edi
    	movl	$0, %eax
    	call	printf
    .L9:
    	movb	$83, -3(%rbp)
    	movb	$83, -2(%rbp)
    	movzbl	-3(%rbp), %eax
    	movb	%al, -1(%rbp)
    	movzbl	-1(%rbp), %eax
    	cmpb	-2(%rbp), %al
    	je	.L10
    	movzbl	-1(%rbp), %ecx
    	movzbl	-2(%rbp), %edx
    	movzbl	-3(%rbp), %eax
    	movl	%eax, %esi
    	movl	$.LC0, %edi
    	movl	$0, %eax
    	call	printf
    .L10:
    	movb	$-42, -3(%rbp)
    	movb	$88, -2(%rbp)
    	movzbl	-3(%rbp), %eax
    	shrb	%al
    	sall	$3, %eax
    	movb	%al, -1(%rbp)
    	movzbl	-1(%rbp), %eax
    	cmpb	-2(%rbp), %al
    	je	.L1
    	movzbl	-1(%rbp), %ecx
    	movzbl	-2(%rbp), %edx
    	movzbl	-3(%rbp), %eax
    	movl	%eax, %esi
    	movl	$.LC7, %edi
    	movl	$0, %eax
    	call	printf
    .L1:
    	leave
    	.cfi_def_cfa 7, 8
    	ret
    	.cfi_endproc
    .LFE0:
    	.size	main, .-main
    	.ident	"GCC: (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2"
    	.section	.note.GNU-stack,"",@progbits
cmd/bat распаковка архива с автоудалением после распаковки
Author: SingleAdwice • 2020-10-30T20:52:08+0000 • Replies: 43 • Views: 8K
Сабж, требуется распаковать пару лямов архивов, чтобы каждый архив
распаковался в папку с именем архива и затем исходный архив удалялся  
если папка с таким именем уже существует и в ней уже есть файлы, то должна
выполнятся перезапись  
  
за решение накину 50$ на пиво
Книга Black Hat Go 2020
Author: SkyFall • 2020-02-22T03:49:33+0000 • Replies: 21 • Views: 7K
Думаю некоторые давно ждали выпуск. Помнится кому то даже предлагали ее
перевести  
<https://www.sendspace.com/file/b0azpp>
LUA VS GO многопоточность
Author: Ar3s • 2019-06-05T19:55:52+0000 • Replies: 17 • Views: 7K
Добрый день друзья!  
Один мой опытный и очень хороший товарищ пару лет назад сказал, что если
необходимо получить качествунную многопоточность, то лучше и надежнее луа я
ничего не найду.  
Сейчас возникла необходимость поднять некий сервис который в 50 потоков/сек
будет опрашивать некий API.  
Нужно отслеживать потоки и делать их максимально отказоустойчивыми. Вот и
вспомнился данный разговор. Сижу и думаю, то ли на GO делать то ли на LUA
смотреть.  
Что бы вы посоветовали из своего опыта?
FWB инжект на masm
Author: barm • 2006-03-13T08:18:03+0000 • Replies: 28 • Views: 7K
Code:Copy to clipboard
    
    
    .386
    .model flat,stdcall
    option casemap:none
    include \masm32\include\windows.inc
    include \masm32\include\kernel32.inc
    includelib \masm32\lib\kernel32.lib
    include \masm32\include\user32.inc
    includelib \masm32\lib\user32.lib
    include \masm32\include\masm32.inc
    includelib \masm32\lib\masm32.lib
    GetPid          PROTO :DWORD
    injected_thread PROTO
    
    CTEXT MACRO y:VARARG
    LOCAL sym, dummy
    dummy EQU $;; MASM error fix
    CONST segment
    IFIDNI <y>,<>
    sym db 0
    ELSE
    sym db y,0
    ENDIF
    CONST ends
    EXITM <OFFSET sym>
    ENDM
    
    .data?
    Buffer      db 256 dup(?)
    ThePID      dd ?
    lpProcess  dd ?
    lpModule    dd ?
    lpNewModule dd ?
    dwSize      dd ?
    lpPID       dd ?
    nBytesWritten dd ?
    .code
    start:
       invoke GetModuleHandle,0
       mov [lpModule], eax
       
       mov edi,eax
       add edi,[edi+3Ch]
       add edi,4
       add edi,14h
       mov eax,[edi+38h]
       mov [dwSize],eax
    ;next thing to do is to get the Process ID (PID)
    ;we can do this 2 ways either CreateToolhelp32Snapshot
    ;Invoke GetPid,CTEXT ('iexplore.exe')
    ;or...
       invoke FindWindow,CTEXT ('IEFrame'),0               ;find iexplorer.exe window class
       invoke GetWindowThreadProcessId, eax, addr ThePID   ;get the PID :)
       invoke OpenProcess,PROCESS_ALL_ACCESS, FALSE, ThePID;open the process
       mov [lpProcess],eax
       invoke VirtualFreeEx, [lpProcess], [lpModule], 0, MEM_RELEASE
       invoke VirtualAllocEx, [lpProcess], [lpModule], dwSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE
       invoke WriteProcessMemory, [lpProcess], eax, [lpModule], [dwSize], addr nBytesWritten
       invoke CreateRemoteThread, [lpProcess], 0, 0, offset injected_thread, [lpModule], 0, ebx
     invoke ExitProcess,0
    
    injected_thread proc
     invoke LoadLibrary,CTEXT ('user32.dll')
     invoke MessageBox,0,CTEXT ('Success!!!'),CTEXT ('Hello From iexplorer'),0
       invoke ExitThread,0
       ret
    injected_thread endp
    
    GetPid proc szFile:dword
     LOCAL Process:PROCESSENTRY32
       mov Process.dwSize, sizeof Process
       invoke CreateToolhelp32Snapshot, 2, 0
       mov esi, eax
       invoke Process32First, esi, addr Process
       @@loop:
       invoke lstrcmpiA,szFile, addr Process.szExeFile
           test eax, eax
           jnz @@continue
       ;if we are here then we got the pid (Process.th32ProcessID}
         push Process.th32ProcessID
         pop ThePID
         jmp @@done
       @@continue:
         invoke Process32Next, esi, addr Process
           test eax, eax
           jz @@done
         jmp @@loop
       @@done:
           invoke CloseHandle, esi
           ret
    GetPid endp
    end start
Погружение в ассемблер. Учимся работать с памятью
Author: tabac • 2020-09-14T19:06:16+0000 • Replies: 18 • Views: 6K
В этой статье я познакомлю тебя с сегментной адресацией и сегментными
регистрами, расскажу, как распределяется первый мегабайт оперативной памяти
компьютера, затем мы обсудим получение прямого доступа к видеопамяти в
текстовом режиме, а самое главное — поностальгируем по фильму «Хакер»! Под
конец напишем психоделическую программу, которой позавидовали бы его герои.  
  
  
**Знакомимся с сегментными регистрами**  
  
Для начала разберемся, что такое сегментные регистры. Процессор 8088 умеет
адресовать один мегабайт оперативной памяти, несмотря на то что регистры у
него 16-битные. В норме 16 битами можно адресовать только 64 Кбайт. И как же
тогда выкручивается 8088? Как ему удается адресовать целый мегабайт? Для этого
в 8088 есть сегментные регистры! Четыре сегментных регистра: CS, ES, DS и SS,
по 16 бит каждый. У каждого из этих регистров есть свое назначение.  
  
Регистр CS указывает на сегмент кода. Процессор обращается к CS всякий раз,
когда надо считать из памяти очередную инструкцию для выполнения.  
  
Регистры DS и ES указывают на сегмент данных. К этим регистрам процессор
обращается, когда выполняемая инструкция считывает или сохраняет данные. Имей
в виду: DS используется чаще, чем ES. ES обычно вступает в игру, когда ты
обрабатываешь массивы данных, индексируя их регистром DI.  
  
Регистр SS указывает на сегмент стека. К этому регистру процессор обращается,
когда выполняет инструкции, взаимодействующие со стеком: push, pop, call и
ret.  
  
Значения, хранимые в сегментных регистрах, — это базовый адрес, поделенный на
16. Если в CS записано значение 0x0000, процессор будет считывать инструкции
из области памяти 0x00000 — 0x0FFFF. Если в регистре CS записано значение
0x1000, то процессор будет считывать инструкции из области памяти 0x10000 —
0x1FFFF.  
  
Если тебе надо адресоваться в какой-то другой сегмент, а не тот, который будет
задействован по умолчанию, напиши этот сегмент в префиксе к инструкции,
которую используешь.  
  
Поместить какое-то число в сегментные регистры напрямую нельзя. Для этого
надо:  
  * либо сначала записать число в какой-нибудь регистр и уже этот регистр присвоить сегментному регистру;
  * либо воспользоваться парой инструкций push/pop;
  * либо воспользоваться инструкциями lds/les.
  
Процессор 8088 настолько лоялен, что позволит тебе даже вот такую инструкцию:
pop cs. Но только имей в виду, что это нарушит поток выполнения инструкций. В
более новых процессорах, начиная с 80286, такую диверсию сделать уже не
получится. И слава богу!  
  
Ну вот вроде бы и все, что тебе надо знать о сегментных регистрах. Теперь ты с
их помощью (в основном с помощью регистров DS и ES) можешь получать доступ ко
всему первому мегабайту памяти ПК.  
  
  
**Как ПК распределяет память**  
Понимание того, как распределяется память в ПК, поможет тебе делать разные
интересные вещи.  
  
Начало загрузки у всех компьютеров одинаковое: они сначала переходят в
текстовый цветной режим 80x25. К видеопамяти экрана, который работает в таком
режиме, можно обращаться напрямую, через вот этот диапазон адресов: 0xB8000 —
0xB8FFF.  
  
Первый байт диапазона — это первый символ в верхнем левом углу экрана. Второй
байт — это цвет фона под символом и цвет самого символа. Затем (третьим
байтом) идет второй символ. И так для всех 25 строк по 80 символов каждая.  
  
Исторический факт. IBM PC образца 1981 года поставлялся в двух модификациях: с
монохромным режимом и с цветным режимом. Тогдашним разработчикам игрушек
приходилось придумывать разные эвристики, чтобы понять, какая у компьютера
графика: монохромная или цветная. Несколько старых добрых игрушек для этого
писали какую-нибудь цифру по адресу 0xB8000 и считывали ее обратно — чтобы
узнать, в каком режиме сейчас идет работа: в цветном или в монохромном.  
  
  
**Прямой доступ к видеопамяти в текстовом режиме**  
Перед тем как мы сможем напрямую обращаться к видеопамяти экрана, то есть без
использования сервисов BIOS, надо задать нужный нам видеорежим.  
  
В этом режиме видеопамять экрана доступна по адресу 0xB8000. Теперь ты можешь
легко получить доступ к ней. Примерно так, как в коде ниже.  
  
Обрати внимание, что после того, как ты выполнил этот кусок кода, ты не
сможешь обращаться к переменным, которые сохраняешь в сегменте кода, как мы
это делали в примерах из прошлых уроков. Потому что DS и ES теперь нацелены не
на сегмент кода, а на видеопамять.  
  
Как же быть? Как вариант, можно перед тем, как нацеливать DS и ES на
видеопамять, сохранить их значение на стеке. Потом нацелиться на видеопамять и
вывести нужные данные на экран. А после этого снять со стека сохраненный
указатель и снова поместить его в DS и ES.  
  
  
Видеопамять, которая отображается на экран, организована вот таким вот
образом.  
  
  
Здесь на каждый символ отведено по два байта. Первый байт — это ASCII-код
буквы. А второй — цвет фона и символа.  
  
  
Кодировка цветов следующая.  
  
  
А теперь давай посмотрим все это на живом примере. Напиши и выполни вот такой
код.  
  
  
Мы здесь задействовали парочку новых инструкций: cld и stosw. Инструкция cld
очищает флаг направления. Зачем нужен этот флаг? Некоторые продвинутые
инструкции (многошаговые) используют его, чтобы понять, что нужно делать с
регистрами SI и DI после очередного шага выполнения: увеличивать их или
уменьшать.  
  
Инструкция stosw записывает значение регистра AX по адресу
ESI
и увеличивает регистр DI на два (размер слова — сдвоенного байта). Обрати
внимание: если флаг направления установлен в единицу (это можно сделать
инструкцией sed), то та же самая инструкция будет не увеличивать DI, а
уменьшать. Тоже на два. Поэтому мы сначала используем cld, поскольку не знаем,
какое на данный момент значение у флага направления.  
  
Всякий раз, когда мы загружаем AX, у нас AL содержит саму букву, которую надо
нарисовать на экране, а AH — цвет символа и цвет его фона (в данном случае
синий фон и разные цвета для каждой буквы).  
  
Когда мы пишем слово (сдвоенный байт) в память, младший байт всегда пишется
первым (в данном случае значение регистра AL), а старший байт идет следом (в
данном случае значение регистра AH).  
  
Таким образом, после того как весь наш текст записан в видеопамять, память
будет заполнена вот так.  
  
  
Теперь ты умеешь рисовать на экране цветные буквы. При желании можешь
поэкспериментировать с символами псевдографики, которые доступны в BIOS.  
  
Кстати, на всякий случай имей в виду, что в 8088 еще есть инструкция stosb.
Она работает так же, как stosw, но только не со словами (сдвоенными байтами),
а с байтами. stosb пишет значение регистра AL по адресу
ESI
и увеличивает DI на единицу (или уменьшает, если флаг направления установлен в
единицу).  
  
  
**Рисуем психоделические круги**  
  
А теперь переходим к самому интересному! Сейчас напишем программу, которая
рисует психоделические круги, как в фильме «Хакер». Помнишь там эпизод, где
наши с тобой коллеги восхищаются «миллионом психоделических оттенков» на ноуте
Кислотного Ожога?  
  
  
Мы нарисуем то же самое, но в классическом текстовом режиме, в разрешении
80x25 с 16 цветами для фона и текста. Итак, приступим.  
  
Сначала инициализируем видеорежим и настраиваем сегменты на видеопамять
экрана.  
  
Потом инициализируем таймер, который поможет добавить динамики к нашей
психоделической анимации. Зачем он нам? Чтобы на первых 32 кадрах анимации
рисовать увеличивающиеся круги, а на остальных 32 — уменьшающиеся.  
  
  
Что тут происходит? Сервис 0x00 прерывания 0x1A считывает, сколько тиков
прошло с того момента, как была загружена система. Результат возвращается в
32-битном виде, помещается в пару регистров:
CXX.  
  
Поскольку для наших нужд надо вести счет только от 0 до 63 и затем обратно, мы
проверяем шестой бит (0x40), и если он установлен в единицу, то добавляем к
текущему значению счетчика знак минус.  
  
Затем инструкцией and al, 0x3F выделяем шесть младших битов и при помощи
вычитания приводим знаковое 8-битное значение к диапазону -32..+31, которое
затем расширяем до слова (до сдвоенного байта). Результат помещаем в CX.  
  
А теперь самое интересное. Вычисляем параметры текущего шага анимации и
отрисовываем ее.  
  
Что мы тут делаем? В DI у нас будет храниться текущая позиция на экране, куда
выводить символ. Сначала сбрасываем ее в 0, чтобы рисовать начиная с левого
верхнего угла. В DH и DL будем хранить номер строки и столбца. А в BX у нас
будет адрес таблицы синусов (ее покажу чуть позже).  
  
Теперь, когда мы проинициализировали все нужные переменные, нам надо вычислить
с помощью таблицы синусов, каким цветом отрисовывать символ (у нас это будет
звездочка) в очередной позиции экрана. Чтобы в итоге получились круги.  
  
Для этого делаем вот что. Берем номер текущей строки (из DH). Умножаем его на
два, чтобы круги были кругами, а не овалами. По этому значению извлекаем синус
из таблицы символов (смотри инструкцию xlat).  
  
Что это за инструкция такая, xlat? Ее мнемоника — это сокращение от слова
trans**lat** e. Она считывает байт с адреса BX+AL и помещает его в регистр AL.
То есть делает то же самое, что инструкция mov, al, [bx+al], но только более
лаконично. Перед тем как обращаться к xlat, надо сначала загрузить в BX адрес
таблицы, а в AL — индекс нужного нам элемента из этой таблицы.  
  
Обрати внимание на префикс CS, который стоит перед xlat. Он говорит
процессору, что сейчас при считывании данных надо обращаться к кодовому
сегменту. Без префикса CS данные будут считаны из сегмента, на который
указывает регистр DS. И получится белиберда, потому что DS сейчас указывает на
экран, а не на код, где размещена таблица синусов. После того как мы извлекли
значение синуса, сохраняем его на стеке (смотри инструкцию push ax).  
  
На этом полдела сделано. Мы взяли номер текущей строки (DH) и вычислили по
нему синус. Дальше делаем то же самое для номера текущего столбца (DL). В
итоге у нас получается два значения синуса. Одно сейчас хранится в регистре
AX, а другое лежит на стеке.  
  
Поэтому мы снимаем со стека предыдущее значение синуса (смотри инструкцию pop
DX) и складываем с текущим значением синуса, которое сейчас хранится в AX. И
еще плюсуем к ним текущее время (в тиках, от момента включения компьютера).
Младший байт полученного результата — это и есть искомое значение цвета (цвет
фона + цвет текста).  
  
Надеюсь, ты не забыл, что всю эту чехарду с синусами мы затеяли для того,
чтобы вычислить, каким цветом отрисовывать звездочку в очередной позиции
экрана и получить в итоге круги?  
  
Итак, нужный цвет мы вычислили и теперь выводим звездочку на экран: mov [di],
ax. Затем добавляем к DI двойку, чтобы перейти на следующую позицию экрана —
где будем рисовать новую звездочку, но уже другим цветом. Ты ведь помнишь, что
у нас на каждый символ отводится по два байта?  
  
Наконец, заключительный штрих: корректируем номера текущей строки и текущего
столбца и переходим к следующей итерации цикла.  
  
Что мы тут делаем? Сначала берем номера текущих строки и столбца (их мы
сохранили на стеке). Помещаем их в DX. Затем прибавляем единицу к DL. Если
результат получился меньше 80 (столько столбцов у нас на экране), то повторяем
цикл. А если досчитали до 80, то переходим на следующую строку: увеличиваем DH
на единицу, а DL обнуляем. Но делаем этот последний шаг, только если не
досчитали до 25. А если в DH у нас уже 25, то переходим в самое начало
программы (смотри метку @@main_loop) и начинаем все заново.  
  
В итоге получается анимация с психоделическими кругами, которые то растут, то
уменьшаются.  
  
Кадр из нашей программы  
  
  
Автор @vedacoder Антон Карев  
хакер.ру
Скрытый запуск powershell скрипта
Author: holder441 • 2019-06-26T15:00:44+0000 • Replies: 6 • Views: 6K
В планировщике задач добавлен вpowershell скрипт, при его выполнении появлется
окно командной строки, есть ли варианты его сткрыть. (-WindowsStyle Hidden
почему то не работает)
Перевод книг про ЯП "Go"
Author: neopaket • 2019-07-06T18:01:20+0000 • Replies: 12 • Views: 6K
Решил начать свою карьеру переводчика на данном форуме и поэтому прошу вас
предложить мне книги для перевода про язык "Go".  
Если книга мне понравится, то я попытаюсь её перевести максимально точно, не
искажая главную мысль.

Конкурс
Author: Chococream • 2011-09-27T10:08:45+0000 • Replies: 15 • Views: 6K
Давно не было у нас интересных конкурсов.  
Предлогаю организовать аналог темы ( <http://xss.is/index.php?topic=10843> ).  
  
**Задание:**  
\- Написать программу-шутку размером не больше 4кб.  
  
**Условия:**  
\- Упаковвывать программу можно.  
\- Язык программирования: не важен, хоть на маш. коде пишите
  
\- Платформа: Windows.  
\- Сроки сдачи: 27.09.2011 - 04.10.2011  
\- Ваши программки слать мне в пм  
(Желательно: запакованные, с паролём. Пароль мне не высылать, т.к я тоже
учавствую).  
  
В конце конкурса (05.10.2011) будет создан топик с релизами, т.о устроим
публичное голосование за звание лучшего кодера DL
  
\- Имена авторов будут скрыты до окончания голосования.  
\- Исходники будут выкладываться по разрешению автора.  
\- Критерии оценки программы: размер, оригинальность.
Вопросики по VB
Author: DiegO • 2011-04-01T13:58:17+0000 • Replies: 22 • Views: 6K
Я пишу трояна на VB, мне что бы он копировался в папку с виндой и там
оставался, но как это сделать не зная букву диска на котором винда? Короче как
узнать путь к системной директории и как сделать что бы он туда копироволся???
Помогите!
Скачать Visual Basic
Author: Reanimator • 2006-03-02T13:51:45+0000 • Replies: 11 • Views: 6K
Здраствуйте люди! Вы не могли бы мне пдсказать где можно скмчать Microsoft
Visual Studio. NET, а то читаю литературку по визуал базик(я в этом деле
новичок, но хочу научиться) и там написано: "Нажмите пуск...... и выберете
Microsoft Visual Studio. NET, я посморел но ниче не нашел или я плохо смотрел
и она идет в поставке вместе с операционкой?
Нужны материалы по Flash
Author: TrueUser • 2011-03-16T07:04:48+0000 • Replies: 2 • Views: 6K
Ребятки, назрела необходимость накрапать кой чего на флеше, может кто
посоветует толковую книжку (желательно со ссылкой) так чтобы действительно
стоящую а не для блондинок.  
А еще сразу бы комплект необходимого софта для писанины (ессно не триального),
потому что просто нет времени колупаться на варезниках и торентах.  
Буду очень благодарен.

*** - Это Не Проблема :)
Author: BUG(O)R • 2005-05-24T17:44:00+0000 • Replies: 11 • Views: 6K
Накануне я нашёл у себя скачанный сто лет назад небольшой исходничок на
ассемблере, который вместо всеми не любимых символов "*" показывает
человеческий текст. К сожалению, или к счастью, в исходнике небыло
коментариев, один сплошной код, который был абсолютно не систематизирован. И
мне стало безумно интересно докапаться до самой сути этой технологии. Как же
всё-таки обойти эти звёздочки, как это делает OpenPass, чем мы хуже?

Ну и подобная бредятина... которая к нашему делу не имеет отношения... В
результате я доработал эту программу и у меня, скажем так, получился более
"красивый" код.  
  
Я выяснил не всё, поэтому эта статья не претендует на полноту, это всего-лишь
мои доводы после нескольких часов исследования.  
  
На самом деле таких прог куча и нужда в такой проге как таковой практически
нулевая, но я наверное такой тормоз, что мне только сейчас захотелось
исследовать принцип работы таких прог. Поэтому статья для такиз же тормозов
как и я

если кого обидел последним высказыванием, то уж извиняйте братья и сестры...
  
  
Итак, мы начинаем...  
  
Кто программирует тот знает, что текстовое поле имеет свойство
**PasswordChar** , и значит в зависимости от значения этого св-ва вы и имеете
возможность видеть или не видеть всё, что находится в текстовом поле! Как
правило для полей куда вводится пароль значение этого св-ва = ***** , для
обычных полей оно пустое т.е. после компиляции равно **00**.  
  
Напишем небольшую программу, форма и текстовое поле со значением св-ва
**PasswordChar = *** , скомпилируем и получаем:  
  
  
  
В уже скомпилированной программе значение этого св-ва зашито, и если мы
дизассемблируем программу, то в памяти сможем легко найти этот символ:  
  
  
  
Значение по этому смещению равно "**2A** ", в десятичном формате это "**42**
", а 42 это и есть ascii код символа "***** ".  
  
Кстати, если перебить эти два полубайта на "**00** ", то собсно и всякие
звёздочки пропадут сами собой, т.е. при вводе в это текстовое поле вы будете
видеть нормальный текст:  
  
  
>>>  
  
  
Но нам этот вариант не подходит, нам надо видеть уже введённое значение(хотя в
хозяйстве может пригодиться).  
  
Как известно любой объект программы(кнопка, текстовое поле, скролбар, метка)
имеет свой уникальный идентификатор - **Handle** , в народе - хендл! И когда
запускается программа каждому объекту присваивается хендл и к хендлу
приклепляются соответствующие св-ва объекта прошитые уже в самой
программе(**TEdit, TButton, TMaskEdit**) . Соответственно любой объект и поле
для ввода пароля будут отличаться друг от друга минимум одним св-ом -
**PasswordChar**. Вот его-то нам с вами и надо отловить из всей кучи объектов.  
  
Приступаем к кодингу, хочу сказать, что код будет на языке ассемблера, поэтому
использовать мы будем одни апи:  
  
Нам надо подумать сначала как же нам получить весь массив объектов для
перебора и сравнения каждого объекта по определяющему типу(поле для ввода
пароля). Есть такая функция: **EnumChildWindows,** которая перечисляет все
дочерние окна принадлежащие родительскому окну и передаёт дескриптор(хендл)
дочернего окна в процедуру обратного вызова(по сути в любую указанную
процедуру). Фу мля... помойму я сложно сформулировал, но ничего, по ходу вы
всё поймёте!  
  
Что ж, теперь стоит вопрос где найти такое родительское окно, чтобы абсолютно
все объекты являлись его дочерними окнами, т.е. объектами создаными после него
и имеющие меньший приоритет. Конечно выход один: делать родительским окном наш
рабочий стол! Что ж, получим хендл рабочего стола в спомощью функции
**GetDesktopWindow**  
  
На данный момент нашей процедуре был передан хендл объекта, теперь она должна
определить не является ли этот объект полем для ввода пароля. Как это сделать?
Это собственно и есть самый трудный этап.  
  
Давайте уже непосредственно перейдём к коду, так думаю будет проще и мне и
вам:  
  
Code:Copy to clipboard
    
    
    (1) main proc hWin:DWORD
    
    (2) invoke GetDesktopWindow
    (3) invoke EnumChildWindows,eax,addr EnumKids,hWin 
    (4) xor eax,eax
    (5) ret
    
    (6) main endp
  
1\. Определяем процедуру и значение **hWin** как 32 разряда т.е. 4 байта.  
  
2\. Вызываем функцию которая и возвратит нам хендл рабочего стола, нашего
родительского окна, от которого мы и начнём перебор объектов.  
  
3\. Вот это и есть главная функция, которая будет перебирать все дочерние окна
относительно десктопа и передавать хендл каждого из них на сравнение процедуре
**EnumKids** , её мы рассмотрим позже.  
  
4\. Обнуляет регистр eax  
  
5\. Возврат из процедуры  
  
6\. Конец процедуры.  
  
Процедура **EnumKids** :  
  
Code:Copy to clipboard
    
    
    (1)EnumKids proc eHandle:DWORD
    
    (2)invoke GetWindowLong,eHandle,GWL_STYLE 
    
    
    (3).if (eax & ES_PASSWORD) 
    
    
    (4)invoke SendMessage,eHandle, EM_SETPASSWORDCHAR, 0, 0 
    (5)invoke SendMessage,eHandle,WM_SETFONT,eax, 0
    
    (6).endif 
    (7)mov eax,eHandle 
    (8)ret
    
    
    (9)EnumKids endp
  
1\. Определяем процедуру и в ней один параметр, 4 байта.  
  
2\. Функция которая и получает стиль или тип нашего объекта, возваращает
характерную для нашего окна информацию.  
  
3\. Вот эта строка будет возвращать два значения, а точнее знака: + и -. В
случае если будет возвращён +,т.е. шестой бит в регистре eax равен 0, то
программа сделает скачек на строчку 7, это будет означать, что наш объект не
будет являться полем со звёздочками, в случае если будет возвращён -, т.е.
шестой бит в регистре будет равен 1(тут с этими битами я сам запутался, но это
не суть важно

), то объект будет являться именно полем с паролем и будет выполнен код
следующий за номерами: 4,5 и 6. Другими словами если стиль не **ES_PASSWORD**
, то идём до строки семь, а если такой стиль принадлежит нашему объекту, то
убиваем звёздочки.  
  
4\. Вы помните св-во **PasswordChar**? Помните, что у нас его значение равно
символу "*"? Так вот эта строчка устанавливает значение св-ва **PasswordChar**
у объекта с хендлом eHandle равное нулю, т.е. попросту говоря мы убиваем это
св-во.  
  
5\. Ну и собсно эта функция и выводит результат в объект с хендлом **eHandle**
текст который и был под свёздочками.  
  
6\. Конец условного оператора  
  
7\. Возвращает хендл, чтобы продолжать перечислять окно.  
  
8\. После команды ret мы опять прыгнем на строчку:  
  
Code:Copy to clipboard
    
    
    invoke EnumChildWindows,eax,addr EnumKids,hWin
  
Определим следующий хендл и процедура **EnumKids** повторится!!!  
  
И так будет пока не будут перечислены все дочерние окна и объекты. Потом будет
выполнена ret в процедуре main и мы вернёмся в главную процедуру.  
  
Вот как это выглядит в отладчике:  
  
Но для начала я определил хендл текстового поля в нашей небольшой программе:  
  
  
  
**Handle: 0x0144**  
  
Теперь смотрите как это выглядит в отладчике:  
  
[Картинка тут](http://www.winux.com.ru/bugor/5.jpg)  
  
Видите в строке выделенной серым цветом(это команда на которой остановился
отладчик после того как программа дошла до хендла который определён нашему
тектовому полю со звёздочками) слово **hWnd** , оно равно 003A0**144** , три
последние цифры совпадают с определённым нами хендлом, значит программа дошла
до нашего текстового поля со звёздочками. Далее, в скобочках, отладчик
показывает св-ва этого поля.И его класс: **ThunderRT6TextBox**. Если бы
программа была написана на делфи, класс был бы определён как **TMaskEdit.**  
  
По-сути наша программа использует всего 5 апи функций, ну и ещё 5 строчек
полезного кода. Я попытался реализовать это на Visual Basic'e, получился, как
это нестранно, гораздо сложночитаемый код, поэтому я решил всё-таки описать
программу на ассемблере.  
  
Ну и плюс ко всему прочему размеры готовых ехе программ на ассемблере и VB:
1536 и 16358 байт соответственно.  
  
Я думаю, что многие что-то здесь поняли не до конца или не поняли вообще.
Возможно я плохой писатель, а возможно вам стоит ещё немного поднатаскаться в
этой области! В любом случае задавайте свои вопросы, я постараюсь ответить,
материал действительно довольно сложный, мне самому понадобилось много времени
чтобы понять всё до конца.  
  
На самом деле данная технология уже не совсем актуальна, и серьёзные программы
не используют такую технологию, но всё-таки такого софта полно.  
  
Например миранда, использует как раз метод защиты который был описан мною
ниже(в случае если пароль не хранится на винте), но если пароль уже введён, а
кнопка OK не нажата, ну вдруг ваш друган отлить отошёл прежде чем нажать на
ОК, а пароль уже ввёл... =), пароль можно узнать используя отладчик, если кому
интересно, то эта тема отдельной статьи... =)  
  
Теперь полный листинг кода программы:  
  
Code:Copy to clipboard
    
    
    ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    
    ;Всякая хрень
    
    .486;Использовать набор команд процессора х486
    .model flat, stdcall;Плоская модель памяти
    option casemap :none;Делаем метки чуствительными к регистру
    
    
    
    include \masm32\include\windows.inc
    include \masm32\include\masm32.inc
    include \masm32\include\gdi32.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\Comctl32.inc
    include \masm32\include\comdlg32.inc
    include \masm32\include\shell32.inc
    include \masm32\include\oleaut32.inc
    
    
    includelib \masm32\lib\masm32.lib
    includelib \masm32\lib\gdi32.lib
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib
    includelib \masm32\lib\Comctl32.lib
    includelib \masm32\lib\comdlg32.lib
    includelib \masm32\lib\shell32.lib
    includelib \masm32\lib\oleaut32.lib
    ;Хрень кончилась :)
    ;<<<<<<<<<<<<<<<<<<<<<< 
    
    ;Объявляем прототипы функций
    EnumKids PROTO :DWORD
    main PROTO :DWORD
    ;<<<<<<<<<<<<<<<<<<<<<< 
    .data
    
    .code
    ;<<<<<<<<<<<<<<<<<<<<<<
    Start:
    
    
    call main;Вызываем процедуру main
    invoke ExitProcess,0;После того как в процедуре main выполнилась команда RET выходим.
    
    ;<<<<<<<<<<<<<<<<<<<<<<
    
    main proc hWin:DWORD
    
    invoke GetDesktopWindow
    invoke EnumChildWindows,eax,addr EnumKids,hWin 
    xor eax,eax
    ret
    
    main endp
    
    ;<<<<<<<<<<<<<<<<<<<<<<
    
    
    EnumKids proc eHandle:DWORD
    
    invoke GetWindowLong,eHandle,GWL_STYLE
    
    .if (eax & ES_PASSWORD)
    
    invoke SendMessage,eHandle, EM_SETPASSWORDCHAR, 0, 0 
    invoke SendMessage,eHandle,WM_SETFONT,eax, 0
    .endif 
    mov eax,eHandle 
    ret
    
    EnumKids endp
    
    ;<<<<<<<<<<<<<<<<<<<<<<
    
    end Start
  
Конечно нельзя обойти стороной метод защиты от такого рода программ. Т.к. я из
языков высокого уровня хорошо знаю VB, то и реализовывать буду на этом языке,
хотя этот метод с лёгкостью можно использовать и в других языках!  
  
Метод немножко ламовский, но зато работает

Я просто отлавливаю символы нажатые в первом текстовом поле(которое доступно
пользователю) во второе текстовое поле(которое можно сделать невидимым,
отключить и вообще вынести за пределы формы, ну кароче спрятать).  
  
Я сделал это так(проверка на значение 8 идёт потому как 8 - это аски код
кнопки BackSpace, соттветственно нам его писать ненадо, он должен выполнять
назначеную ему функцию):  
  
Code:Copy to clipboard
    
    
    Private Sub Text1_KeyPress(KeyAscii As Integer)
    If KeyAscii <> 8 Then
    Text2 = Text2 & Chr(KeyAscii)
    Text1 = Text1 & "*"
    KeyAscii = 0
    Else
    On Error Resume Next
    Text2.Text = Mid(Text2.Text, 1, Len(Text2.Text) - 1)
    Text1.Text = Mid(Text1.Text, 1, Len(Text1.Text) - 1)
    End If
    End Sub
  
Скачать снифер: [сЦылка](http://www.k0dery.h15.ru/simbol42/sniff.rar)  
  
Скачать не защищённую программу:
[сЦылка](http://www.k0dery.h15.ru/simbol42/project1.rar)  
Скачать программу с защитой:
[сЦылка](http://www.k0dery.h15.ru/simbol42/project2.rar)  
  
При написании статьи были использованы следующие инструменты:  
  
OllyDBG, HiewDemo, The Customizer, MASM & MS VB 6.0 =)  
  
Оригинал: <http://www.k0dery.h15.ru/simbol42/simbol42.htm>
Программирование на ассемблере на платформе x86-64
Author: Wolfomeo • 2013-01-22T16:14:18+0000 • Replies: 17 • Views: 5K

  
Автор: **Аблязов Р.З.**  
Формат: **PDF**  
Размер архива с примерами исходных текстов: **14 МБ.**  
  
Скачать: <http://rghost.ru/43234073>  
Зеркало: <http://www.sendspace.com/file/0iby8v>
Как войти в малварь кодинг на ассемблере?
Author: Ott_Fon_Bismark • 2021-02-20T20:43:26+0000 • Replies: 49 • Views: 5K
Добрий день, хотелось би изучить ассемблер но столкнулса с кучей компиляторов
,те кто разбирается что посоветуете новичку?
Алгоритм работы кейлоггера
Author: Quake3 • 2014-09-13T21:36:58+0000 • Replies: 16 • Views: 5K
Как я понял, существуют три способа (я говорю о юзермоде, кернел не
интересует) логирования клавиатурного ввода:  
1\. Опрос в цикле функций состояния клавиатуры
GetKeyboardState/GetAsyncKeyState и так далее.  
2\. Хуки.  
3\. перехват функций, оконных сообщений и т.п.  
  
1\. Из того, что я понял в ходе изучения, эти функции - самое простое и самое
первое, к чему приходит любой разработчик подобного софта. Ну а что - бери да
вызывай в цикле и логируй, что там получилось. Но по факту, есть некоторые
нюансы. Если слишком часто вызывать функцию (например - GetAsyncKeyState ,
опрос каждой клавиши), то это нагрузка на проц + будет логироваться несколько
раз подряд одно и тоже (вида - вводишь "а", а он логирует "ааа"). Если слишком
редко - часть символов пролетит. Нередко логирование было не в том порядке,
что нужно - вместо "слово" логировалось "совло" и подобное. Если для обычной
переписки это еще куда не шло (понять суть можно), то для логирования паролей,
ес-но, не подойдет. Поигравшись с этими функциями, я так и не понял, как их
оптимально использовать - наверное, все таки никак (или в комплексе с чем-то
другим).  
  
2\. Более точный вариант, т.к. просто - получил сигнал что ввели новый символ,
залогировал. С другой стороны, хуки - это дополнительная нагрузка на ОС, это
страшное палево, и (возможно) нестабильность работы. Кто-то писал, что кривые
хуки (вместе с аверами) могут уронить систему в бсод.  
  
3\. Экзотика - из-за этого нестабильная работа, ну и палево (перехват функций
это обычно инжект).  
  
В общем, интересует ваше мнение на эту тему, особо мнение тех, кто реверсил
такую малварь. Что чаще всего используют, плюсы и минусы.
WinInet
Author: Quake3 • 2012-02-06T14:15:50+0000 • Replies: 23 • Views: 5K
Подскажите по WinInet - как получить страницу сайта после авторизации? Т.е.
чтобы передались куки и все прочее. Авторизация на сайте идет так:  
  
Code:Copy to clipboard
    
    
    .486                      
    .model flat, stdcall      
    option casemap :none      
    
    include \masm32\include\windows.inc
    include \masm32\include\wininet.inc
    include \masm32\macros\macros.asm
    include \masm32\macros\windows.asm
    uselib kernel32, masm32, user32,wininet
    
    .data
    uri db "/login.php?action=in",0
    login_cont db 256 dup (0)
    login_shab db "form_sent=1&redirect_url=&req_username=%s&req_password=%s&login=%C2%EE%E9%F2%E8",0
    login db "user1",0
    pass db "111222",0
    headers db 13,10,"Accept: text/html,application/xhtml+xml,application/xml",
    13,10,"Accept-Language: ru-ru,ru;q=0.8,en-us",
    13,10,"Accept-Charset: windows-1251",
    13,10,"Keep-Alive: 115",
    13,10,"Connection: keep-alive",
    13,10,"Content-Type: application/x-www-form-urlencoded",0
    buf db 1024 dup (0)
    
    lpszReferer db "http://te.mybb.ru/login.php",0
    
    .data?
    hInetSes dd ?
    hConnect dd ?
    hReq dd ?
    bReaded dd ?
    
    .code
    start:
    
    invoke wsprintf,addr login_cont,addr login_shab,addr login,addr pass
    invoke InternetOpen,chr$("Mozilla/5.0"),INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0
    mov hInetSes,eax
    invoke InternetConnect,hInetSes,chr$("te.mybb.ru"),INTERNET_DEFAULT_HTTP_PORT,\
    0,0,INTERNET_SERVICE_HTTP,0,0
    	.if eax==0
      Invoke MessageBox,0,LastError$(),chr$("InternetConnect fail"),0
    	.endif
    mov hConnect,eax
    
    invoke HttpOpenRequest,hConnect,chr$("POST"),addr uri,0,addr lpszReferer,\
    0,INTERNET_FLAG_KEEP_CONNECTION,0
    	.if eax==0
      Invoke MessageBox,0,LastError$(),chr$("HttpOpenRequest fail"),0
    	.endif
    mov hReq,eax;handle of request
    invoke HttpSendRequest,hReq,addr headers,sizeof headers,addr login_cont,sizeof login_cont
    	.if eax==0
      Invoke MessageBox,0,LastError$(),chr$("HttpSendRequest fail"),0
    	.endif
    Invoke Sleep,3000
    invoke InternetCloseHandle,hInetSes
    Invoke ExitProcess,0
    end start
  
Пробовал после Sleep писать что-то вида InternetReadFile, передавая hReq, но
показывает мне лишь страницу входа (точнее, сообщение что вход успешен, сейчас
вас перенаправят на главную страницу). А как мне считать другую страницу,
будучи залогиненным? Нужно новый запрос через HttpOpenRequest формировать?
Книги по VB
Author: Winux • 2005-07-17T12:47:16+0000 • Replies: 5 • Views: 5K
  
Visual Basic .Net "Библия пользователя"  
Билл Ивьен, Джейсон Берес  
1024 стр. - 101 Мб.  
 [Скачать
часть 1](http://rapidshare.de/files/3079478/a.part1.rar.html)  
 [Скачать
часть 2](http://rapidshare.de/files/3082262/a.part2.rar.html)  
 [Скачать
часть 3](http://rapidshare.de/files/3083050/a.part3.rar.html)