jueves, 23 de octubre de 2008

Definición de Ingeniería Inversa

La ingeniería inversa se ha definido como el proceso de construir especificaciones de un mayor nivel de abstracción partiendo del código fuente de un sistema software o cualquier otro producto (se puede utilizar como punto de partida cualquier otro elemento de diseño, etc)...



Estas especificaciones pueden volver ser utilizadas para construir una nueva implementación del sistema utilizando, por ejemplo, técnicas de ingeniería directa.




La aplicación de ingeniería inversa nunca cambia la funcionalidad del software sino que permite obtener productos que indican cómo se ha construido el mismo. Se realiza permite obtener los siguientes beneficios:




Reducir la complejidad del sistema.


Generar diferentes alternativas.


Recuperar y/o actualizar la información perdida (cambios que no se documentaron en su momento).


Detectar efectos laterales.


Facilitar la reutilización.


La ingeniería inversa puede ser de varios tipos:




Ingeniería inversa de datos: Se aplica sobre algún código de bases datos (aplicación, código SQL, etc) para obtener los modelos relacionales o sobre el modelo relacional para obtener el diagrama entidad-relación


Ingeniería inversa de lógica o de proceso: Cuando la ingeniería inversa se aplica sobre código de un programa para averiguar su lógica o sobre cualquier documento de diseño para obtener documentos de análisis o de requisitos.


Ingeniería inversa de interfaces de usuario: Se aplica con objeto de mantener la lógica interna del programa para obtener los modelos y especificaciones que sirvieron de base para la construcción de la misma, con objeto de tomarlas como punto de partida en procesos de ingeniería directa que permitan modificar dicha interfaz.

viernes, 17 de octubre de 2008

Bios, passwords y otras hierbas

Bueno aqui publico como se resetean los bios , no exactamente es todo código sino mas bien metodos, si bien tambien posteare algunos codigos implementados en c, Pascal, Delphi, Ensamblador y otros lenguajes.

Bueno aqui va:
Cómo desactivar la contraseña de una BIOS

Hay tres formas de desactivar una contraseña. Dos de estas formas son relativamente sencillas de llevar a cabo:

La primera consiste en abrir la CPU y quitar la pila de la placa base, esperar de 3 a 5 segundos y volverla a colocar. Al quitar la pila los datos de la CMOS se pierden, incluida la contraseña. La mayoría de las placas base incluyen unos jumpers que permiten resetear la CMOS sin necesidad de extraer la pila.

La segunda forma consiste en eliminar la contraseña provocando un error en la BIOS del sistema. Cuando se guarda la configuración de una BIOS, esta (casi todas las versiones lo hacen) genera un CRC en la que intervienen los parámetros de dicha configuración. Cuando se accede a la BIOS, dicho programa realiza de nuevo la operación del CRC y lo compara con el resultado que tenía previamente almacenado. De esta forma verifica que no se ha cambiado ningún dato de manera intencionada o por error. Si así sucediera, la BIOS reinicia los datos de la CMOS y con ellos el password, el cual deja de estar activo y permite el acceso a la BIOS.

El problema de estas dos formas de desactivación de un password reside en que en los dos casos se pierde la configuración del sistema.

La tercera forma es específica, mediante programación.


Codificación de un password de la BIOS Award

El algoritmo en cuestión es bastante deficiente y el resultado de dicho algoritmo es un dato de tipo word sin signo (2 bytes) que se guarda en una posición de la CMOS que puede variar con respecto a la versión de esta. Algunas versiones de esta BIOS guardan dos passwords pero usan el mismo método de codificación.

La codificación es bien simple. Consiste en sumar el código ASCII de cada una de las letras que forman el password, pero antes de pasar a sumar la siguiente letra, multiplica el resultado por 4. Es decir, coge una letra, lo multiplica por 4, le suma la segunda, multiplica este resultado por 4 y así hasta sumar la última letra del password (máximo 8 caracteres). Como he dicho, el resultado se almacena en 2 bytes, el número entero sin signo más alto que se puede representar en 2 bytes es 65535. Si el resultado del algoritmo es mayor a 65535, se divide ese resultado entre 65536. Toma el resultado entero obtenido de esa división y lo suma al resto de dicha división. Ese dato obtenido será el entero sin signo (2 bytes) que se almacenará en la CMOS.

La verdad es que a nivel de código de máquina es más sencillo. Trabaja sobre un registro de tipo word, tamaño de dos bytes. Realiza la suma del ASCII de cada letra y hace un desplazamiento de bits dos posiciones hacia la izquierda. Al final, si el flag de acarreo está activado, es decir, si en cualquiera de los desplazamientos a la izquierda, se escapa algún bit, le suma al resultado un 1.

Por ejemplo... Si el password en cuestión es Dragon
El código ASCII de estas letras es: D = 68 r =114 a = 97 g =103 o = 111 n =110
Teniendo el cuenta que inicialmente el resultado = 0, sumamos y multiplicamos por 4 cada resultado:
(4 * 68) + 114 = 386
(4 * 386) + 97 = 1641
(4 * 1641) + 103 = 6667
(4 * 6667) + 111 = 26779
(4 * 26779) + 110 = 107226

Lo que hay que hacer en este caso es dividir 107226 entre 65536, quedarnos con el resto, y al resto sumarle el nº de múltiplos de 65536 obtenido:
107226 / 65536 = 1 , resto = 41690 >> 41690 + 1 = 41691.

Para no complicarse la existencia, como las operaciones de suma y multiplicación no van a dar un resultado cuyo tamaño en memoria sea superior a 3 bytes, no sería necesario hacer divisiones. Bastaría con restar al nº obtenido 65535, va a dar lo mismo 107226 - 65535 = 41691. En definitiva, es truncar el resultado si es mayor de 65535.

El resultado es 41691 que separado en 2 bytes es 162 y 219 ((162 * 256) + 219).

Este algoritmo es deficiente porque este resultado se puede obtener con mas de una (mas de 200000) combinaciones de caracteres diferentes.

Sabiendo esto, es fácil implementar un programa que codifique o descodifique dicho password para poder acceder así a cualquier BIOS. De todas formas también se puede implementar un programa que descodifique el password por fuerza bruta, pero eso... es otra historia ^_^.



Cómo acceder a la CMOS

A la CMOS de cualquier placa base (PC) se accede mediante 2 puertos físicos:

El puerto 112 (70h) de escritura, en el que se indica la dirección o posición del dato que se va a leer o escribir en la CMOS. El tamaño máximo de una CMOS suele ser de 256 bytes y cada BIOS usa un nº determinado de estos bytes, normalmente hasta 128. Luego el rango de escritura en ese puerto va de 0 a 255.
El puerto 113 (71h) de lectura/escritura en el que se lee o escribe el dato de la posición indicada en el puerto 112.


Códigos de ejemplo para resetear la CMOS ya sea Award, Ami Bios o la que sea

Para causar un error de CRC en la BIOS solo es necesario cambiar uno de los datos que intervienen el la operación de dicho CRC o el resultado en si. Si no se sabe cuál es la posición en la que se encuentra dicho resultado o los datos que intervienen en esa verificación lo más seguro es reescribir toda la CMOS con un dato aleatorio. El siguiente código logra nuestro propósito.

Lenguaje C++

#pragma hdrstop
#include
#include
#include

#pragma argsused
int main(int argc, char **argv)
{
char buffer[83];
char *p;

printf("Programado por Emiliano Traba");
buffer[0] = 1;
p = cgets(buffer);
asm
{
mov dx, 70h
mov al, 00000
out dx, al
int 21h
}
}

Lenguaje Pascal/Delphi

procedure ResetCMOS;
var intPos: integer;
begin
for intPos := 0 to255 do
begin
port[112] := intPos;
port[113] := 1;
end;
end

Lenguaje Ensamblador

MOV CX, 00FFh;
@Bucle:
MOV DX, 70h;
MOV AX, CX;
OUT DX, AX;
MOV DX, 71h;
MOV AX, 1h;
OUT DX, AX;
LOOP @Bucle;

o bien

mov dx, 070h
mov al, 02Eh
out dx, al
inc dx
xor al, al
out dx, al

Con el debug de DOS

* debug
* o 70 2E
* o 71 FF
* Q

o bien

* debug
* o 70 17
* o 71 17
* Q

Con QBasic o Basic

* 10 OUT &H70,17
* 20 OUT &H71,0

o bien

* OUT &H70,&H17 UT &H71,&H17


Una vez ejecutado ese código y reiniciado el ordenador la BIOS presentará un mensaje de error de CRC, reseteará los datos de la CMOS y entrará automáticamente en la BIOS para configurar de nuevo el sistema. En ese momento el sistema ya es nuestro. Podemos reactivar disquetera, anular otros dispositivos etc...



Códigos de ejemplo sobre codificación del pass de una BIOS Award y AmiBios

Con unos mínimos conocimientos en programación, a partir de la descripción dada sobre la codificación de un password en una BIOS Award podemos generar un código que haga dicha función. El propósito de este código sería devolver un entero a partir de un password que nosotros tecleemos. Damos por validado que ese password no es mayor de 8 letras.

Código en Pascal para bios Award:

function EncodePass(strPass: string): integer;
var intPos: integer;
LngRes: longint;
begin
intPos := 1;
lngRes := 0;
while intPos <= ord(strPass[0]) do
begin
lngRes := (lngRes * 4) + ord(strPass[intPos]);
inc(intPos);
end;
if lngRes > 65535 then
lngRes := (lngRes div 65536) + (lngRes mod 65536);
Result := lngRes;
end;

El resultado de esta función es un entero de 2 bytes. Para separar el resultado de la función en 2 bytes no hay mas que dividir ese dato por 256, quedarnos con el número de múltiplos obtenido en esa división y su resto. De tal forma que un entero esta compuesto por (múltiplos*256)+resto)

Nota: Delphi dispone de las funciones Hi() y Lo() para separar ambos bytes.


Una vez resuelta esta función, sólo quedaría saber en qué posición de la CMOS se guarda ese resultado, observar si guarda primero el byte de mayor peso o biceversa y hallar de qué manera afecta ese dato en la operación de CRC para generar un CRC válido. Esta operación es sencilla y no tiene mas complicación que realizar comparaciones de los passwords introducidos en la BIOS con los datos modificados en la CMOS.



Descodificación del pass de una BIOS Award

Hay dos formas de conseguir el password de una Award. Directamente por ingeniería inversa, o por fuerza bruta. A continuación se detallan las dos formas.

Por Fuerza bruta:

Este método consiste en realizar constantemente comparaciones de una cadena literal generada por software y codificada (ver función EncodePass) con el resultado existente en la CMOS, hasta encontrar aquella cadena cuya codificación coincida con dicho resultado. No necesariamente debe terminar cuando encuentre una cadena literal válida. Se puede continuar el escaneo para observar que el número de contraseñas válidas es inmenso, demostrando la deficiencia del algoritmo empleado por estas BIOS. Como contrapunto señalar que este método es bastante lento.

El siguiente ejemplo muestra una función a la que se le pasa el entero que hay en la CMOS (intCmos) y devuelve solamente una cadena válida, si la hay:


Lenguaje Delphi:

function GetPass(intCmos: integer): string;
var arrCadena: array[0..7] of char;
intPos: byte;
bfound, bOk, bTop: Boolean;
strResultado: string;
begin
bFound := False;
bTop := False;
strResultado := '';
strPCopy(arrCadena, ' '); // Llenamos el buffer con espacios
while (not bFound) and (not bTop) do
begin
intPos := 0;
bOk := False;
repeat // Generamos cadena literal
if ord(arrCadena[intPos]) = 255 then
begin
arrCadena[intPos] := chr(32);
inc(intPos);
if intPos = 8 then bTop := True; // Todas las cadenas evaluadas...
end else
begin
arrCadena[intPos] := chr(ord(arrCadena[intPos]) + 1);
bOK := True;
end;
until bOk or bTop;
if bOK then
begin
bFound := (EncodePass(string(arrCadena)) = intCmos);
if bFound then strResultado := string(arrCadena);
end;
end;
Result := strResultado;
end;



Por ingeniería inversa:

Este método consiste en tratar de conseguir un password válido realizando para ello el proceso contrario a la operación de codificación (y = x + 2 >> x = y - 2). Para ello lo que se trata de hacer es restar del dato de la CMOS un valor, dividirlo entre 4, y así sucesivamente procurando que el ultimo resto sea mayor de 32 y menor de 122, asegurando así que ese password no contiene caracteres especiales. Si el último valor no se encuentra en ese rango hay que retroceder y probar con otro valor. Así hasta encontrar un password válido, que no tiene por qué ser el introducido en un principio (de hecho, es improbable que lo sea). La ventaja del método de ingeniería inversa sobre la fuerza bruta es indudable. El resultado es instantáneo.



En el siguiente código pasamos el entero que contiene la CMOS y la función devolverá un password válido generado por el método de ingeniería inversa. Este código no verifica la existencia de caracteres especiales en el password generado pero no es difícil implementarlo.



function GetPassAward(intCmos:integer): string;
var strTexto: string;
intLetra: integer;
begin
strTexto := '';
while intCmos > 123 do
begin
intLetra := 122;
while ((intCmos - intLetra) mod 4) <> 0 do
dec (intLetra);
strTexto := chr(intLetra) + strTexto;
intCmos := (intCmos - intLetra) div 4;
end;
strTexto := chr(intCmos) + strTexto;
Result := strTexto;
end;



Notas:

Las BIOS AWARD dependiendo de la versión, guardan 1 o 2 contraseñas.

La primera contraseña se encuentra en las posiciones 28 (1Ch) y 29 (1Dh) de la CMOS, siendo 1Ch el byte menos significativo.

El CRC para la primera contraseña consiste en sumar los bytes desde la posición 16 (10h) a la 45 (2Dh) inclusive de la CMOS y el resultado de dos bytes los guarda en las posiciones 46 (2Eh) y 47 (2Fh), siendo 2Fh el byte menos significativo.

El byte de la posición 17 (11h) de la CMOS (concretamente los dos primeros bits) contiene la información que indica que el password está activado (bits a 1) o desactivado (bits a 0). Para ponerlos a 0 solo habría que aplicar la máscara AND 0x11111100 (FCh) a dicho byte.

La segunda contraseña se encuentra en las posiciones 96 (60h) y 97 (61h) de la CMOS, siendo 60h el byte menos significativo. El CRC y los bits de des/activación del password no los he comprobado.

Decodificación del pass de una bios Ami


Lenguaje QBasic:

seed = reg(0) AND &HF0

PRINT "Calculating."
FOR count = 1 TO 6
PRINT ".";
bioschar = reg(count)
decchar = 0
IF bioschar <> 0 THEN
DO
decchar = decchar + 1
pass = 0
FOR bit = 0 TO 7
IF (&HC3 AND 2 ^ bit) = 2 ^ bit AND (seed AND 2 ^ bit) = 2 ^ bit THEN
pass = (pass + 1) MOD 2
END IF
NEXT bit
seed = INT(seed / 2) + pass * 128
LOOP WHILE seed <> bioschar
bpass$ = bpass$ + CHR$(decchar)
ELSE
count = 6
END IF
NEXT count


Award:
* 01322222
* 1EAAh
* 256256
* 589589
* 589721
* ?award
* admin
* alfarome
* aLLy
* aPAf
* award
* award_?
* award.sw
* AWARD SW
* AWARD_SW
* AWARD_PW
* award_ps
* AWARD?SW
* awkward
* BIOS
* bios*
* biostar
* biosstar
* CONCAT
* CONDO
* condo
* djonet
* efmukl
* g6PJ
* h6BB
* HELGA-S
* HEWITT RAND
* HLT
* j09F
* j256
* j262
* j322
* j64
* lkw peter
* lkwpeter
* PASSWORD
* SER
* setup
* SKY_FOX
* SWITCHES_SW
* Sxyz
* SZYX
* t0ch88
* t0ch20x
* ttptha
* TTPTHA
* TzqF
* wodj
* ZAAADA
* zbaaaca
* zjaaadc
* zjaaade

Ami:
* ami
* amidecod
* amipswd
* AMIPSWD
* AMI
* A.M.I.
* aammii
* AMI~
* amiami
* AMI.KEY
* AMISETUP
* AMI?SW
* AMI!SW
* AMI_SW
* bios310
* BIOSPASS
* CMOSPWD
* KILLCMOS
* 589589
* ami.kez
*ami°
* helgaßs
* HEWITT RAND

Vobis:
* merlin

Advance Integration:
* Advance

ALDI (Medion):
* medion

Amptron:
* Polrty

AST:
* SnuFG5

Biostar:
* Biostar
* Q54arwms

Concord:
* last

CTX International:
* CTX_123

CyberMax:
* Congress

Daytek und Daewoo:
* Daytec
* Daewuu

DELL:
* DELL

Digital Equipment:
* komprie

Enox:
* xo11nE

Epox:
* central

Freetech:
* Posterie

HP Vectra Serie:
* hewlpack

IBM:
* IBM
* MBIUO
* sertafu

Iwill
* iwill

Jet Way:
* spoom1

Joss Technology:
* 57gbz6
* Technolgi

MachSpeed:
* sp99dd

Magic-Pro:
* prost

Megastar:
* Star

Micron:
* sldkj754
* xyzall

Micronics:
* dn_04rjc

M Technology:
* mMmM

Nimble:
* xdfk9874t3

Packard Bell:
* Bell9

QDI:
* QDI

Quantex:
* teX1
* xljlbj

Research:
* Col2ogro2

Shuttle:
* Spacve

Siemens Nixdorf:
* SKY_FOX

Speedeasy:
* lesarot1

SuperMicro:
* ksdjfg934t

TMC:
* BIGO

Toshiba:
* 24Banc81
* Toshiba
* toshy99

Vextrec Technology:
* Vextrec

WIMBIOSnbsp BIOS v2.10:
* Compleri

Zenith:
* 3098z
* Zenith

Zeos:
* zeosx

Compaq:
*compaq

Tinys:
*Tiny

METHOD _____ SYSTEM

* Del during boot _____ AMI, Award
* Esc during boot _____ Toshiba
* F1 during boot _____ Toshiba; Phoenix; Late model PS/1 Value Point and 330s
* F2 during boot _____ NEC
* F10 when square in top RH corner of screen _____ Compaq
* Ins during boot _____ IBM PS/2s w/ Reference Partition
* Reset twice _____ Some Dells
* Alt Enter _____ Dell
* Alt ? _____ Some PS/2s
* Ctrl-Esc _____ General
* Ctrl Ins _____ Some PS/2s when pointer at top right of screen
* Ctrl Alt Esc _____ AST Advantage, Award, Tandon
* Ctrl Alt + _____ General
* Ctrl Alt S _____ Phoenix
* Ctrl Alt Ins _____ Zenith, Phoenix
* Ctrl S _____ Phoenix
* Ctrl Shift Esc _____ Tandon 386
* Shift Ctrl Alt + Num Pad Del _____ Olivetti PC Pro
* Setup disk _____ Old Compaqs, Epson (Gemini), IBM, IBM PS/2, Toshiba, most old 286s

Regiones para tus forms en vb6

Hola ahora voy a postear como dibujar regiones para derle la forma que quieras a tus forms en vb6, es un antigüo codigo que tengo generado por Arturo Guzman Guerra, que me ha servido en algunos programas que he hecho.


En fin aqui va el codigo con explicación:

Declaraciones de constantes , tipos y funciones:

'Región con las partes que se interpolan entre dos regiones
Public Const RGN_AND = 1
'Región mediante la copia de una de las regiones origen
Public Const RGN_OR = 2
'Región con las partes de dos regiones que no se solapan
Public Const RGN_XOR = 3
'Región con las partes de una región que no interseccionan con la otra
Public Const RGN_DIFF = 4
'Región mediante la copia de una de las regiones origen
Public Const RGN_COPY = 5
'Redundantes pero bueno
Public Const RGN_MAX = RGN_COPY
Public Const RGN_MIN = RGN_AND

'Tipo de dato RECT
Public Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type

Public Type POINTAPI
x As Long
y As Long
End Type

'Región eliptica o circular mediante 4 coordenadas
Public Declare Function CreateEllipticRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
'Región eliptica o circular mediante una estructura RECT
Public Declare Function CreateEllipticRgnIndirect Lib "gdi32" (lpRect As RECT) As Long
'Región poligonal
Public Declare Function CreatePolygonRgn Lib "gdi32" (lpPoint As POINTAPI, ByVal nCount As Long, ByVal nPolyFillMode As Long) As Long
'Región consistente en una serie de poligonos
Public Declare Function CreatePolyPolygonRgn Lib "gdi32" (lpPoint As POINTAPI, lpPolyCounts As Long, ByVal nCount As Long, ByVal nPolyFillMode As Long) As Long
'Región rectangular
Public Declare Function CreateRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
'Región rectangular con una estructura RECT
Public Declare Function CreateRectRgnIndirect Lib "gdi32" (lpRect As RECT) As Long
'Región rectangular con los bordes redondeados
Public Declare Function CreateRoundRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long, ByVal X3 As Long, ByVal Y3 As Long) As Long
'Para convinar varias regiones en una
Public Declare Function CombineRgn Lib "gdi32" (ByVal hDestRgn As Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode As Long) As Long
'Establece la región en la ventana correspondiente
Public Declare Function SetWindowRgn Lib "user32" (ByVal hWnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long

Forma de uso, en este caso se toma la forma rectangular con bordes redondeados, el cual lleva 6 valores el primer par son X1 e Y1, los cuales son lado izquierdo y parte superior del form, X2 e Y2, lado derecho y parte posterior del form, y por último X3 e Y3, este ultimo par da el grado de redondeo de cada esquina es un valor para los cuatro vertices , solo que con un valor separado para las X y otro para las Y, en fin aca va su aplicación:

Public Sub EstablecerRegionPruebas()
Dim Retorno As Variant
Dim RGN, RGN2 As Long
RGN = CreateRoundRectRgn(10, 0, 320, 190, 40, 40)
Retorno = SetWindowRgn(frmPruebas.hWnd, RGN, True)
End Sub

jueves, 16 de octubre de 2008

Apariencia de Windows XP y Vista en tu programa VB6

Cito un post que vi:

Hola este es mi primer post y aqui posteo este módulo que tengo guardado de hace mucho tiempo.

El módulo que postearé es el que utilizo para que mis programas en vb6 se vean con el formato de Windows XP y Vista. Para ello deben tildar alguno de los componentes "Microsoft Windows Common Controls X.X"

Luego crean el siguiente modulo, el cual tendra el proceso principal (Void Main o Sub Main depende del lenguaje):


Option Explicit


Public Type tagInitCommonControlsEx
lngSize As Long
lngICC As Long
End Type

Public Declare Function InitCommonControlsEx Lib "comctl32.dll" (iccex As tagInitCommonControlsEx) As Boolean



Public Const ICC_USEREX_CLASSES = &H200

Public Sub Main()

On Error Resume Next

Dim iccex As tagInitCommonControlsEx
With iccex
.lngSize = LenB(iccex)
.lngICC = ICC_USEREX_CLASSES
End With
InitCommonControlsEx iccex
Form1.Show
On Error GoTo 0
End Sub

Por último agregan el archivo de recursos que aqui les dejo para descargar, el cual deben agregarlo en "Documentos Relacionados"