Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - .:UND3R:.

#1272
Tutorial Russian Dolls crackme
Autor: Andrewl
información del crackme:http://crackmes.de
Autor del tutorial:UND3R
Objetivos: Realizar Keygen

Abrimos el crackme directamente, observaremos que nos informa el número de dígitos del serial:


Si introducimos un serial falso nos mostrará el siguiente mensaje:


Abrimos el crackme desde OllyDbg y veremos el siguiente Entry Point:


Buscamos referencias de texto dentro del crackme:


Notaremos la cadena de texto "Congratulations!", hacemos doble clic para dirigirnos hacia la dirección en donde es utilizada:


Vemos una instrucción PUSH, encargada de meter el puntero de la cadena de texto en el stack y luego una instrucción JMP SHORT que permite la utilización de la misma call hacia la API MessageBoxA permitiendo el ahorro de instrucciones:


Si subimos un poco veremos que para que el crackme nos muestre el mensaje de "Congratulations!" se deben cumplir ocho comparaciones. Si alguna de las ocho nos da como resultado cero (Activación de la bandera ZF) nos mostrará el mensaje equivalente al introducir un serial falso. Para obtener el mensaje de un serial correcto se debería cumplir las siguientes afirmaciones:

Citar00402D78   .  807C24 11 00  CMP BYTE PTR SS:[ESP+11],0
Stack SS:[0012FAC5]=01

00402D7F   .  807C24 14 00  CMP BYTE PTR SS:[ESP+14],0
Stack SS:[0012FAC8]=01

00402D86   .  807C24 13 00  CMP BYTE PTR SS:[ESP+13],0
Stack SS:[0012FAC7]=01

00402D8D   .  807C24 17 00  CMP BYTE PTR SS:[ESP+17],0
Stack SS:[0012FACB]=01

00402D94   .  807C24 16 00  CMP BYTE PTR SS:[ESP+16],0
Stack SS:[0012FACA]=01

00402D9B   .  807C24 15 00  CMP BYTE PTR SS:[ESP+15],0
Stack SS:[0012FAC9]=01

00402DA2   .  807C24 10 00  CMP BYTE PTR SS:[ESP+10],0
Stack SS:[0012FAC4]=01

00402DA9   .  807C24 12 00  CMP BYTE PTR SS:[ESP+12],0
Stack SS:[0012FAC6]=01

* (Otra manera sería invertir los nemónicos de instrucciones JE SHORT por JNE SHORT)

También vemos un CALL ESI llamativo ya que este podría ser el encargado de comprobar si el serial introducido corresponde a un serial válido, coloquemos un BP en él:


Iniciamos el crackme (F9) e introducimos un serial falso:


Notaremos que se ha detenido en nuestro BP:


Entramos al CALL ESI y veremos lo siguiente:


Traceamos algunas instrucciones hasta llegar a la instrucción XOR:


Si pasamos la instrucción XOR (F7), notaremos que han cambiado algunas instrucciones posteriores a JNZ SHORT. Esto se debe a una función de descifrado en donde el contenido de ESI es alterado producto de la operación booleana XOR entre [ESI] y 76, guardando el resultado en el operando de destino (dentro de ESI). Luego de eso es incrementado ESI para apuntar a las siguientes instrucciones y disminuido ECX, este segundo registro es utilizado como contador de bucle ya que luego de SUB ECX,1 hay un nemónico de instrucción de tipo salto condicional en donde salta a la instrucción XOR si el resultado de la instrucción SUB ECX,1 es distinto de cero:


Colocamos un BP a continuación de JNZ SHORT e iniciamos el crackme (F9):


Veremos una serie de instrucciones descifradas:


Quitamos el BP y traceamos (F7), notaremos las siguientes instrucciones encargadas de la validación del serial:
0FB648 03       MOVZX ECX,BYTE PTR DS:[EAX+3] ; mueve el cuarto valor del serial a ECX
83F9 6D         CMP ECX,6D                    ; lo compara con 6D (m)


En caso de que la comparación de como resultado la activación de la bandera Cero (ZF), se moverá dentro de EDX el byte 1:
MOV BYTE PTR DS:[EDX],1



Si miramos el valor de EDX en los registros de propósito general de 32 bits veremos que EDX apunta a una de las ocho direcciones que debe contener 1 byte para que el serial sea considerado como válido:


Si seguimos traceando (F7) notaremos una función encargada de cifrar las instrucciones previamente descifradas:


Seguimos traceando (F7), veremos nuevamente el procedimiento de descifrado:


Colocamos un BP a continuación de la instrucción JNZ SHORT:


Iniciamos nuevamente el crackme (F9) y notaremos que se repiten nuevamente los procedimientos:


podríamos resumirlo de la siguiente manera:
-descifra las instrucciones a ejecutar
-ejecuta las instrucciones descifradas encargadas de verificar el serial
-cifra las instrucciones previamente ejecutadas


(Lo más probable es que el programa cifre las instrucciones ejecutadas para evitar que al retornar del CALL ESI queden descubiertas todas las instrucciones de comprobación del serial, al igual que luego de introducir un serial si es dumpeado el ejecutable, quedarían expuestas las comprobaciones.)

Si seguimos traceando notaremos que siempre se repiten las mismas funciones:
0015E028    0FB648 03       MOVZX ECX,BYTE PTR DS:[EAX+3] ; mueve el cuarto valor del serial a ECX
0015E02F    83F9 6D         CMP ECX,6D                    ; lo compara con 6D (m)

0015E069    0FB648 02       MOVZX ECX,BYTE PTR DS:[EAX+2] ; mueve el tercer valor del serial a ECX
0015E070    83F9 37         CMP ECX,37                    ; lo compara con 37 (7)

0015E0AA    0FB648 03       MOVZX ECX,BYTE PTR DS:[EAX+3] ; mueve el cuarto valor del serial a ECX
0015E0B1    83F9 65         CMP ECX,65                    ; lo compara con 65 (e)

0015E0EB    0FB648 07       MOVZX ECX,BYTE PTR DS:[EAX+7] ; mueve el octavo valor del serial a ECX
0015E0F2    83F9 48         CMP ECX,48                    ; lo compara con 48 (H)

0015E12C    0FB648 03       MOVZX ECX,BYTE PTR DS:[EAX+3] ; mueve el cuarto valor del serial a ECX
0015E133    83F9 37         CMP ECX,37                    ; lo compara con 37 (7)

0015E16D    0FB648 00       MOVZX ECX,BYTE PTR DS:[EAX]   ; mueve el primer valor del serial a ECX
0015E174    83F9 37         CMP ECX,37                    ; lo compara con 37 (7)

0015E1AE    0FB648 01       MOVZX ECX,BYTE PTR DS:[EAX+1] ; mueve el segundo valor del serial a ECX
0015E1B5    83F9 55         CMP ECX,55                    ; lo compara con 55 (U)

0015E1EF    0FB648 01       MOVZX ECX,BYTE PTR DS:[EAX+1] ; mueve el segundo valor del serial a ECX
0015E1F6    83F9 64         CMP ECX,64                    ; lo compara con 64 (d)

0015E230    0FB648 04       MOVZX ECX,BYTE PTR DS:[EAX+4] ; mueve el quinto valor del serial a ECX
0015E237    83F9 47         CMP ECX,47                    ; lo compara con 47 (G)

0015E271    0FB648 02       MOVZX ECX,BYTE PTR DS:[EAX+2] ; mueve el tercer valor del serial a ECX
0015E278    83F9 37         CMP ECX,37                    ; lo compara con 37 (7)

0015E2B2    0FB648 01       MOVZX ECX,BYTE PTR DS:[EAX+1] ; mueve el segundo valor del serial a ECX
0015E2B9    83F9 55         CMP ECX,55                    ; lo compara con 55 (U)

0015E2F3    0FB648 07       MOVZX ECX,BYTE PTR DS:[EAX+7] ; mueve el octavo valor del serial a ECX
0015E2FA    83F9 6F         CMP ECX,6F                    ; lo compara con 6F (o)

0015E334    0FB648 05       MOVZX ECX,BYTE PTR DS:[EAX+5] ; mueve el sexto valor del serial a ECX
0015E33B    83F9 37         CMP ECX,37                    ; lo compara con 37 (7)

0015E375    0FB648 03       MOVZX ECX,BYTE PTR DS:[EAX+3] ; mueve el cuarto valor del serial a ECX
0015E37C    83F9 36         CMP ECX,36                    ; lo compara con 36 (6)

0015E3B6    0FB648 01       MOVZX ECX,BYTE PTR DS:[EAX+1] ; mueve el segundo valor del serial a ECX
0015E3BD    83F9 33         CMP ECX,33                    ; lo compara con 33 (3)

0015E3F7    0FB648 04       MOVZX ECX,BYTE PTR DS:[EAX+4] ; mueve el quinto valor del serial a ECX
0015E3FE    83F9 45         CMP ECX,45                    ; lo compara con 45 (E)

0015E438    0FB648 02       MOVZX ECX,BYTE PTR DS:[EAX+2] ; mueve el tercer valor del serial a ECX
0015E43F    83F9 50         CMP ECX,50                    ; lo compara con 50 (P)

0015E479    0FB648 02       MOVZX ECX,BYTE PTR DS:[EAX+2] ; mueve el tercer valor del serial a ECX
0015E480    83F9 36         CMP ECX,36                    ; lo compara con 36 (6)

0015E4BA    0FB648 05       MOVZX ECX,BYTE PTR DS:[EAX+5] ; mueve el sexto valor del serial a ECX
0015E4C1    83F9 39         CMP ECX,39                    ; lo compara con 39 (9)

0015E4FB    0FB648 05       MOVZX ECX,BYTE PTR DS:[EAX+5] ; mueve el sexto valor del serial a ECX
0015E502    83F9 49         CMP ECX,49                    ; lo compara con 49 (I)

0015E53C    0FB648 00       MOVZX ECX,BYTE PTR DS:[EAX]   ; mueve el primer valor del serial a ECX
0015E543    83F9 35         CMP ECX,35                    ; lo compara con 35 (5)

0015E57D    0FB648 02       MOVZX ECX,BYTE PTR DS:[EAX+2] ; mueve el tercer valor del serial a ECX
0015E584    83F9 7A         CMP ECX,7A                    ; lo compara con 7A (z)

0015E5BE    0FB648 01       MOVZX ECX,BYTE PTR DS:[EAX+1] ; mueve el segundo valor del serial a ECX
0015E5C5    83F9 6E         CMP ECX,6E                    ; lo compara con 6E (n)

0015E5FF    0FB648 03       MOVZX ECX,BYTE PTR DS:[EAX+3] ; mueve el cuarto valor del serial a ECX
0015E606    83F9 6A         CMP ECX,6A                    ; lo compara con 6A (j)

0015E640    0FB648 01       MOVZX ECX,BYTE PTR DS:[EAX+1] ; mueve el segundo valor del serial a ECX
0015E647    83F9 7A         CMP ECX,7A                    ; lo compara con 7A (z)

0015E681    0FB648 06       MOVZX ECX,BYTE PTR DS:[EAX+6] ; mueve el séptimo valor del serial a ECX
0015E688    83F9 57         CMP ECX,57                    ; lo compara con 57 (W)

0015E6C2    0FB648 05       MOVZX ECX,BYTE PTR DS:[EAX+5] ; mueve el sexto valor del serial a ECX
0015E6C9    83F9 4F         CMP ECX,4F                    ; lo compara con 47 (O)


Por lo que podríamos crear un script de ODbg encargado de almacenar todas las comparaciones que realiza. Al realizar comprobaciones de los datos obtenidos por el script, los serial ingresados eran considerados como incorrectos por lo que por lógica deberían haber más comparaciones que si se cumplen se introduce un byte 0, por lo que encontré funciones muy similares pero con la gran diferencia que si estas se cumplían en vez de poseer la instrucción MOV BYTE PTR DS:[EDX],1 a continuación de JNZ SHORT, contenían la instrucción MOV BYTE PTR DS:[EDX],0, a consecuencia de esto cree un script que en un documento de texto me mostrara la comparación junto con un SI o un NO en donde SI es introducido cuando la instrucción siguiente a JNZ SHORT es MOV BYTE PTR DS:[EDX],1 y un NO cuando la instrucción siguiente a JNZ SHORT es MOV BYTE PTR DS:[EDX],0

Script:
Código (asm) [Seleccionar]
VAR AUX
VAR FSERIAL
VAR SERIAL
WRT "log.txt","Log:"                                                 
INICIO:
TICND  "byte [eip]==75 && byte [eip+1]==0F7" 
BP eip+2
RUN
BC eip
TICND  "byte [eip]==8B && byte [eip+1]==55"
STI
CMP edx,0012FAC5
JE ENCONTRADO
CMP edx,0012FAC8
JE ENCONTRADO
CMP edx,0012FAC7
JE ENCONTRADO
CMP edx,0012FACB
JE ENCONTRADO
CMP edx,0012FACA
JE ENCONTRADO
CMP edx,0012FAC9
JE ENCONTRADO
CMP edx,0012FAC4
JE ENCONTRADO
CMP edx,0012FAC6
JE ENCONTRADO
JMP INICIO
ENCONTRADO: 
MOV FSERIAL,ecx
BUF FSERIAL
STR FSERIAL 
MOV SERIAL,[eip+2],1
BUF SERIAL
STR SERIAL
STI
ADD eip,2
CMP [eip],C6,1
JNE INICIO
CMP [eip+1],02,1
JNE INICIO
CMP [eip+2],01,1
JE SI
NO:
MOV AUX,"NO"
JMP CONTINUAR
SI:
MOV AUX,"SI"
CONTINUAR:
WRTA "log.txt",FSERIAL
WRTA "log.txt","=",""
WRTA "log.txt",SERIAL,""
WRTA "log.txt"," ",""
WRTA "log.txt",AUX,"" 
jmp INICIO


El script debe ser ejecutado de la siguiente forma:
1)colocar BP en CALL ESI
2)iniciar el crackme (F9)
3)introducir el serial: 12345678 (ya que nos dará la referencia de la posición del dígito que se está comparando)
4)Se detendrá en el BP se debe quitar y entrar dentro del CALL (001CFFE8    55              PUSH EBP)

El script debe ser detenido una vez que hemos presionado aceptar a la alerta generada por la API MessageBoxA del serial incorrecto.

Una vez terminado el script si abrimos log.txt (documento de texto creado por el script) veremos lo siguiente:

En la primera linea:
el cuarto carácter es comparado con m y si este se cumple mueve dentro de EDX el byte 1.

Ya que el script logea las comparaciones de manera secuencial, la lógica sería buscar desde abajo hacia arriba una comparación con SI y luego buscar hacia abajo la misma comparación con un NO, si se encuentra la comparación el dígito es inválido en caso contrario el dígito es válido, para optimizar la búsqueda utilizaremos Excel, seleccionamos todo el contenido de log.txt y lo pegamos dentro de una nueva hoja de Excel:


Nos dirigimos a Datos->Filtro:


En la ubicación A1 ("Log:") contendrá un botón:


Seleccionamos el botón y nos vamos a Filtros de texto-> Comienza por...:


He introducimos 1:


De esta forma Excel filtrará de manera secuencial todos los datos que comienza con 1, en otras palabras nos mostrará todas las comparaciones realizadas con el primer dígito:


Copiamos el contenido filtrado en un nuevo documento de texto, nos dirigimos hasta el final y comenzamos a buscar "SI" de la siguiente manera:

De manera lógica estamos buscando la última comparación válida del dígito 1

Ya encontrado el "SI" buscamos hacia abajo la igualdad válida para saber si es anulada por un "NO" (En este caso está a la vista, pero en los demás dígitos no son tan visibles las igualdades válidas que más abajo se ven afectadas por un "NO"):


Si no se encuentra la comparación hemos encontrado un dígito válido:

en caso contrario debemos volver al "SI" encontrado y buscar nuevamente "SI" hacia arriba ya encontrado el primer dígito se debe filtrar nuevamente en Excel pero esta vez por los que comienzan en 2 y repetir el procedimiento de búsqueda hasta encontrar los ocho dígitos.

Una vez encontrado los ocho dígitos al introducir el serial, el crackme nos mostrará el siguiente mensaje:


Ya con un serial válido podemos obtener un Keygen:
1)debemos introducir el serial válido.
2)EJ: CAaC5EEs.
3)Si queremos saber todas las posibilidades del primer dígito vamos introduciendo números desde el "0" al "9", luego letras mayúsculas desde la "A" a la "Z" y letras minúsculas desde la "a" a la "z".

Pero el mensaje del serial incorrecto nos es un poco molesto, por lo que podríamos borrarlo, nos dirigimos a la string: "sorry, try harder!":


y llenamos con instrucciones NOP (Not operand) y agregamos un JMP tal como lo muestra la imagen:


Guardamos los cambios y ya podremos obtener los dígitos válidos para cada posición del serial con mayor comodidad.

La lista completa de posibles combinaciones es la siguiente:
   1ºD   2ºD   3ºD   4ºD   5Dº   6Dº   7ºD   8ºD
VA 1     4     2     8     4     7     1     4
   C     A     a     C     5     E     E     s
         B                 D     F
         C                 J     H
         E                 Ñ     K
         J                 P     L
         K                 U     M
         M                 ñ     N
         Ñ                       Ñ
         O                       Q
         Q                       R
         R                       S
         V                       U
         Z                       V
         a                       W
         g                       X
         i                       Y
         k                       g
         m                       h
         q                       i
         s                       j
         y                       ñ
                                 o
                                 q
                                 t
                                 z


Keygen:
Para el Keygen he tenido que suprimir las letras Ñ y ñ en cuanto a la generación del serial debido a que estoy iniciándome en el lenguaje ASM y estoy utilizando procedimientos pre-diseñados por lo que desconozco como solucionarlo y como trabajar directamente con APIS por lo que el Keygen es muy simple, pero cumple con su finalidad, aquí el código de fuente:

Código (asm) [Seleccionar]
TITLE Keygen Russian Dolls (Keygen-Russian-Dolls.asm)
; Genera combinaciones de dígitos válidos para el crackme Russian Dolls
; Autor: UND3R
; Fecha: Miércoles 4 de enero de 2012
INCLUDE c:\masm32\include\Irvine32.inc
INCLUDELIB c:\masm32\lib\kernel32.lib
INCLUDELIB c:\masm32\lib\Irvine32.lib
INCLUDELIB c:\masm32\lib\User32.lib
.data
; en el arreglo SegundoDigito se ha omitido la letra Ñ
; en el arreglo QuintoDigito se ha omitido la letra Ñ y ñ
; en el arreglo SextoDigito se ha omitido la letra Ñ y ñ
PrimerDigito  BYTE 31h,"C"
SegundoDigito BYTE 34h,"A","B","C","E","J","K","M","O","Q","R","V","Z","a","g","i","k","m","q","s","y"
TercerDigito  BYTE 32h,"a"
CuartoDigito  BYTE 38h,"C"
QuintoDigito  BYTE 34h,35h,"D","J","P","U"
SextoDigito   BYTE 37h,"E","F","H","K","L","M","N","Q","R","S","U","V","W","X","Y","g","h","i","j","o","q","t","z"
SeptimoDigito BYTE 31h,"E"
OctavoDigito  BYTE 34h,"s"
Serial        BYTE 8 DUP(?)
Color         BYTE ?

.code
main PROC
    call GetTextColor              ; obtiene el color de texto y fondo de la consola
mov Color,al                   ; mue AL dentro del arreglo Color
    call Randomize                 ; inicializa el valor de la semilla para el procedimiento RandomRange
    call GenerarSerial
    call MostrarSerial
jmp main
main ENDP
GenerarSerial PROC
; Genera seriales válidos de manera aleatoria
; RECIBE:   NADA
; DEVUELVE: Serial válido en el arreglo sin inicializar "Serial"
;--------------------------------------------------------------------
mov eax,sizeof PrimerDigito    ; mueve a EAX el número de valores del arreglo
call RandomRange               ; genera números aleatorios desde 0 hasta EAX - 1
mov dl,[PrimerDigito+eax]      ; mueve a DL un valor aleatorio del arreglo "PrimerDigito"
mov [Serial],dl                ; mueve DL dentro del arreglo "Serial"

mov eax,sizeof SegundoDigito   ; mueve a EAX el número de valores del arreglo
call RandomRange               ; genera números aleatorios desde 0 hasta EAX - 1
mov dl,[SegundoDigito+eax]     ; mueve a DL un valor aleatorio del arreglo "SegundoDigito"
mov [Serial+1],dl              ; mueve DL dentro del arreglo "Serial"

    mov eax,sizeof TercerDigito    ; mueve a EAX el número de valores del arreglo
call RandomRange               ; genera números aleatorios desde 0 hasta EAX - 1
mov dl,[TercerDigito+eax]      ; mueve a DL un valor aleatorio del arreglo "TercerDigito"
mov [Serial+2],dl              ; mueve DL dentro del arreglo "Serial"

mov eax,sizeof CuartoDigito    ; mueve a EAX el número de valores del arreglo
call RandomRange               ; genera números aleatorios desde 0 hasta EAX - 1
mov dl,[CuartoDigito+eax]      ; mueve a DL un valor aleatorio del arreglo "CuartoDigito"
mov [Serial+3],dl              ; mueve DL dentro del arreglo "Serial"

mov eax,sizeof QuintoDigito    ; mueve a EAX el número de valores del arreglo
call RandomRange               ; genera números aleatorios desde 0 hasta EAX - 1
mov dl,[QuintoDigito+eax]      ; mueve a DL un valor aleatorio del arreglo "QuintoDigito"
mov [Serial+4],dl              ; mueve DL dentro del arreglo "Serial"

mov eax,sizeof SextoDigito     ; mueve a EAX el número de valores del arreglo
call RandomRange               ; genera números aleatorios desde 0 hasta EAX - 1
mov dl,[SextoDigito+eax]       ; mueve a DL un valor aleatorio del arreglo "SextoDigito"
mov [Serial+5],dl              ; mueve DL dentro del arreglo "Serial"

mov eax,sizeof SeptimoDigito   ; mueve a EAX el número de valores del arreglo
call RandomRange               ; genera números aleatorios desde 0 hasta EAX - 1
mov dl,[SeptimoDigito+eax]     ; mueve a DL un valor aleatorio del arreglo "SeptimoDigito"
mov [Serial+6],dl              ; mueve DL dentro del arreglo "Serial"

mov eax,sizeof OctavoDigito    ; mueve a EAX el número de valores del arreglo
call RandomRange               ; genera números aleatorios desde 0 hasta EAX - 1
mov dl,[OctavoDigito+eax]      ; mueve a DL un valor aleatorio del arreglo "OctavoDigito"
mov [Serial+7],dl              ; mueve DL dentro del arreglo "Serial"
ret

GenerarSerial ENDP
MostrarSerial PROC
    mov ecx,8                      ; establece ECX = 8
    mov esi,0                      ; establece ESI = 0
    L2:
    mov eax,16                     ; establece EAX = 16
    call RandomRange               ; Genera un número aleatorio entre 0 y EAX - 15
cmp eax,0                      ; compara EAX con 0
je L2                          ; si EAX = 0 se dirige a la etiqueta L2 (Evita un texto negro junto con un fondo de igual color)
call SetTextColor              ; Cambia el color de texto y de fondo de la consola, de acuerdo al valor de AL
    L1:
mov al,[Serial+esi]            ; mueve los dígitos del arreglo "Serial" a AL
call WriteChar                 ; escribe un dígito del arreglo "Serial" en la consola
inc esi                        ; aumenta en uno esi
loopd L1                       ; decrementa ECX y si ECX no es cero se dirige a la etiqueta L1
call Crlf                      ; desplaza el cursor abajo, hacia la derecha
mov al,[Color]                 ; mueve el contenido del arreglo Color a AL
call SetTextColor              ; Cambia el color de texto y de fondo de la consola, de acuerdo al valor de AL
call WaitMsg                   ; se espera que el usuario presiona alguna tecla para continuar
call Clrscr                    ; limpia el contenido de la consola
ret

MostrarSerial ENDP
END main


En el cada vez que presionemos una tecla nos mostrará seriales distintos:


IMPORTANTE:
Si el serial es copiado directamente y no es introducido de manera manual o ni si quiera un dígito, el crackme lo considera como inválido pudiendo ser este verdadero.

UND3R




Pack de descarga:
-Crackme modificado sin el mensaje de serial incorrecto
-Código de fuente Keygen .asm
-Seriales correctos.txt
-Crackme
-Keygen
-Script
-log.txt

LINK: http://www.mediafire.com/?nxlnml8nx4i8dvb
#1273
Cita de: Karman en  4 Enero 2012, 02:20 AM


Por algo las comillas " " si es que te referías a mi  :P
#1274
Hola bienvenido ahora 2012 es el mismo vas bien, suerte y si tienes dudas pregunta :D
#1275
Excelente, muchísimas gracias a ambos me ha servido  ;-)

de verdad muchas gracias :D
#1276
pues eso ya que trae un botón que dice borrar datos repetidos, pero no considera las mayúsculas y minúsculas

#1277
Disculpa que reabra esto, pero existe alguno parecido que deje guardado la palabra repetida y que distinga entre mayúsculas y minúsculas? saludos
#1278
Ahora se cambian los papeles.. quien hace virus y quien hace antivirus, en cuanto al tema aclarar que un usuario aquí ya ha dado esa idea pero otros usuarios anti modernista y cosas por el estilo lo insultaron de loco y no ético debido a que actúa sin el consentimiento del dueño del SO... 
#1279
Hola, sabes lo probé y funciona bien pero me surge el siguiente problema:

si los números son:

1
1
2
3
2
4


solo borra 1, el 2 no es borrado, creo que solo compara con la línea que está abajo
#1280
Cita de: EleKtro H@cker en  2 Enero 2012, 03:41 AM
¿Es totalmente necesario hacerlo con un script?

Podrías ahorrarte mucho trabajo con el comando:
Uniq -U Token4.txt > Finish.txt

uniq --help

Usage: uniq [OPTION]... [INPUT [OUTPUT]]
Discard all but one of successive identical lines from INPUT (or
standard input), writing to OUTPUT (or standard output).

Mandatory arguments to long options are mandatory for short options too.
 -c, --count           prefix lines by the number of occurrences
 -d, --repeated        only print duplicate lines
 -D, --all-repeated[=delimit-method] print all duplicate lines
                       delimit-method={none(default),prepend,separate}
                       Delimiting is done with blank lines.
 -f, --skip-fields=N   avoid comparing the first N fields
 -i, --ignore-case     ignore differences in case when comparing
 -s, --skip-chars=N    avoid comparing the first N characters
 -u, --unique          only print unique lines
 -w, --check-chars=N   compare no more than N characters in lines
     --help     display this help and exit
     --version  output version information and exit


EDITO:
http://gnuwin32.sourceforge.net/downlinks/coreutils-bin-zip.php




No necesariamente, la idea es que de la forma que sea cumpla su objetivo, probaré el programa, muchísimas gracias :D