-[ 0x08 ]-------------------------------------------------------------------- -[ SET de caracteres ]------------------------------------------------------- -[ by ilegalfaq ]----------------------------------------------------SET-30-- SET de caracteres ================= 01.Introduccion 02.Resumen 03.Fe de ratas 04.ASCII, SBCS, DBCS y MBCS 05.Unicode y UTF 06.Algoritmo BIDI 07.Sets en navegadores 08.Passwords y Unicode 09.Portapapeles 10.Compilando Unicode en Windows 11.Fuentes 12.Vaya mierda... 13....tan buena 14.Despedida 15.Principales referencias 01.Introduccion --------------- Hace tiempo lei [ref.1] que el LC3 [L0pht Crack 3, crackeador de passwords de cuentas de usuario en Windows con tecnologia NT], soporta la entrada de contrase=as en varios alfabetos, como el griego, el cirilico o el arabe. Contrase=as en varios alfabetos... mmmm... ¿y si me pongo en mi cuenta de correo una password en chino? ¿o si protejo mis archivos con una password en arabe? Eso no tendria que aparecer en ningun diccionario de los pocos que he visto hasta ahora, todos ellos con palabras inglesas o espa=olas. ¿Se resistiran a los crackeadores de passwords, incluso a la fuerza bruta? Tampoco solemos tener los teclados con los drivers para chino o arabe. ¿Se resistiran a los keyloggers? Tampoco se pueden comunicar facilmente a otras personas. ¿Se resistiran a la Ingenieria Social? En algunos casos estas passwords pueden torear a crackeadores, keyloggers y actos de IS, pero en otros casos se lo pueden dejar mucho mas facil. Para demostrarlo, pasen y vean con sus propios ojos el infinito mundo de los sets de caracteres. 02.Resumen ---------- El set de caracteres mas usual en el mundo informatico ha sido el ASCII. El Unicode se perfila cada vez mas como el set a utilizar en todo el mundo, ya que contempla los caracteres de todos los alfabetos. Los sistemas y programas que trabajan con Unicode [p.ej. WindowsNT y Word97, respectivamente] ofrecen ventajas que no ofrecen los que no lo contemplan [p.ej. Windows9x y NotePad, respectivamente]. Nos fijaremos en los recuperadores de passwords, los compiladores de C, los navegadores de Internet y los editores de texto. Tambien se veran fugazmente las fuentes, la API de copiar y pegar, al algoritmo BIDI (ya que para los ejemplos se utilizara texto en arabe), y los pros y contras del Unicode. 03.Fe de ratas -------------- Muchos datos de este articulo pueden ser erroneos o falsas apariencias. Para evitar mas errores no he tratado ningun otro SO mas que el Windows98. Los programas y SDK's que he utilizado son de versiones algo viejas, y como explicare no soportan el Unicode muy bien, a diferencia de los mas nuevos. Podria comprar nuevo software, pero como soy algo rata en este aspecto, prefiero tener fe en lo que otras personas han escrito sobre los sets. L'ha pillao? Cuñaaa-aa-a-a-a...!!! 04.ASCII, SBCS, DBCS, MBCS y otras chicas del monton ---------------------------------------------------- Much@s de vosotr@s creeis saber lo que es el ASCII. El American Standard Code for Information Interchange es un codigo para representar como numeros a los caracteres ingleses [ref.2]. ¡¡Co=o!! ¡¡Si hubieran sido espa¤oles o portorriquenyos la e~e se veria como una eñe!! Asi, cada letra tiene asignado un numero que va del 0 al 127. Por ejemplo, la 'a' es el 61. Los codigos del '00'x al '1F'x (31) son caracteres de control (retorno de carro, tabulador, etc...). El ASCII utiliza 7 bits para cada caracter. Si se utiliza el octavo, entonces se habla de ASCII extendido, que dispone de 128 caracteres mas, la mayoria simbolos, letras con acentos y otras historias. Tambien de 8 bits es el ISCII (India) o el ArmSCII (Armenia). Segun la ref.3, los sets de caracteres [o 'code pages'] de un byte como ASCII e ISCII se llaman SBCS [Single Byte Character Set]. Otros ejemplos de SBCS que os pueden sonar son los siguientes: - Los ANSI [American National Standards Institute]. Son los utilizados por la GDI [Graphics Device Interface] de Windows. Yo tengo por defecto el ANSI 1252 (Latin 1), que es lo que me aparece con GetACP(), o en: HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Nls\Codepage\ACP - OEM [Original Equipment Manufacturer], utilizado por la FAT del MS-DOS. Supongo que esta es la explicacion de por que escribir con el Edit del MD-DOS no es sinonimo de escribir en ASCII. En mi Autoexec.bat me aparece el OEM 850: 'mode con codepage select=850', lo mismo que retorna la funcion GetOEMCP(), y lo mismo que aparece en: HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Nls\Codepage\OEMCP - EBCDIC [Extended Binary Coded Decimal Interchange Code], utilizado por los viejos mainframes. Vale, muy bien. Pero ¿ya caben todas las letras del alifato arabe, todas las hiragana y katagana japonesas, los caracteres griegos y los cirilicos, ideogramas chinos y coreanos, las miles de silabas indias y el alfabeto gallego en las solo 256 combinaciones de ocho bits!?? Pues no. Por eso, un mismo codigo puede ser un caracter distinto segun el SBCS que se este utilizando. Por ejemplo, el codigo 202 o 'CA'x para los que usamos el ANSI 1252 (Latin 1), se trata de la letra 'Ê' [E mayuscula con un acento circunflejo]. En cambio, para los arabes, como que tienen el ANSI 1256, 'CA'x no significa la 'E' con acento circunflejo, sino la letra 'teh'. Fijateh. De mostrar una cosa u otra se encarga el sistema en base a las fuentes y a los sets de trabajo que tienen asociadas. Las matrices contenidas en los cp_nnnn.nls (en Windows95/98/ME) o los c_nnnn.nls (NT,2K,XP) parecen hacer el resto [ref.10]. Igualmente, 256 codigos siguen siendo pocos para algunas escrituras. Es por eso que aparecieron los DBCS [Double Byte Character Sets], como el ISCLAP de los indios. Con 2 bytes ya podemos hacer muchas combinaciones, hasta 65536, suficiente para los millares de glifos indios, chinos, coreanos... No contentos con eso, chinos, japoneses y coreanos [triada CJK], forzaron la aparicion de los MBCS [Multi Byte Character Sets], con bits para todos los gustos, como por ejemplo los JIS japoneses, el GB 2312-80 chino y el KS C 5601-1992 coreano. Calculo que debe haber varios cientos de sets pululando por el mundo. Tanto set no puede ser bueno ;), sobretodo a efectos de compatibilidad entre sistemas y aplicaciones. Un poco de orden se hace inevitable. Pero como el ser humano es como es, en vez de idear un set que englobara a todos los caracteres, glifos y escrituras, ideo mas de uno: el Unicode, el ISO-10646, el TCC [TRON Character Code]... ¿Por que es tan dificil ponerse de acuerdo? Afortunadamente los 2 primeros se mantienen en paralelo. Los 127 primeros caracteres de todos estos sets suelen coincidir con los del ASCII, para no liar todavia mas la caotica situacion. Las APIs de Windows y las librerias estandar de C, asi como diferentes algoritmos con licencia GNU, tienen macros que realizan rapidamente conversiones entre los multiples SBCS, DBCS, MBCS y Unicode. ¿Marea??? Pues creo que no tanto como a los gobiernos asiaticos, que han acabado dando un corte de manga a Microsoft y a unas cuantas empresas occidentales. Han preferido pasar de ser una opcion local, o una variedad periferica, o una configuracion regional, a ser el pilar de un sistema operativo hecho por ellos y para ellos. Tanta conversion de sets y bypasses como el MS-IME [Input Method Editor, en Windows asiaticos] no les acaba de convencer, y mas cuando no esta adaptado a la perfeccion a sus escrituras. Tambien estan hartos de las licencias inflexibles, asi que lo van a desarrollar como codigo abierto. Mucha suerte. Creo que tendra que ver con el proyecto TRON [ref.20], que es un sistema con su propio set universal alternativo al Unicode, y que lleva 20 a=os siendo desarrollado por la Universidad de Tokio con codigo abierto. ¿Alternativo al que? Al Unicode, veamoslo con mas detalle. 05.Unicode y UTF ---------------- Unicode es un set de caracteres que proporciona un solo codigo para un solo caracter. Esto es, un codigo numerico refleja solo un caracter o glifo. Pero no al reves: por ejemplo, la letra B es identica a la letra griega beta mayuscula, aunque son codigos Unicode difentes. O la letra arabe 'teh' es el codigo U+062A pero tambien el U+FE95. La version 4 de Unicode dispone de mas de 70.000 codigos, pero puede llegar a codificar desde el U+0000 hasta el U+10FFFF [=1.114.111, que gracia que tienen los palindromos, ¿a que si?], y la cifra se dispara si entramos en codigos de uso privado. Incluye los caracteres de casi todas las escrituras, como el chino, japones, griego, arabe, incluso el Braille de los ciegos!! Un escueto html-javascript para convertir Unicode <--> Glifo es el siguiente (funcionamiento variable segun navegador y configuracion), aunque lo hace mejor charmap.exe de WindowsNT, o infinitamente mejor SC Unipad. /*--UnicodeGlifo.htm --------------------------------------------------*/

/*----------------------------------------------------------------------*/ Este estandar se hace necesario si no se quiere corromper la informacion en un mundo cada vez mas multicultural y multidireccional. Si tu tienes un servidor que lee con un set de caracteres y le llega informacion con otro formato, pues cagado la hemos si no puede hacer la conversion. Por ejemplo, si te llega un mail escrito en tailandes y lo lees con un programa que solo reconoce griego, patapam!, no lo entendera ni un tailandes ni un griego [ni un frances ni una cubana]. Por eso la gran mayoria de internacionales informaticas ya han adoptado el Unicode, y todos los sistemas operativos modernos ya lo soportan. ¿Todos? Todos no, todavia resisten frente al invasor los irreductibles Windows9x. Afortunadamente hay aplicaciones como las de Office-97 o Internet Explorer que soportan Unicode aunque sea en Windows9x. Un ejercicio interesante es ver un archivo Unicode. Escribamos la letra arabe 'teh' en un documento .doc de Word (es una letra que parece una sonrisa con dos puntitos encima como si fueran ojos). Puedes copiarlo de una pagina .htm y pegarlo en el .doc, o puedes insertarlo directamente en el .doc desde la opcion 'Insertar -> Simbolo'. Guardemoslo como 'texto unicode'. Lo siguiente es observarlo con un visor hexadecimal (p.ej. hiew): FF FE 2A 06 0D 00 0A 00 Vemos que no aparece el valor 'CA'x del ANSI 1256, sino 8 bytes. ¿Por que? . FFFE hace referencia al sentido en que hay que leer los pares de bytes. Es el llamado BOM [Byte Order Mark]. Resulta util en los archivos para los que no se sabe si son little endian [el byte mas significativo de los almacenados en memoria es el ultimo] o big endian [es el primero]. FFFE expresa little endian, y FEFF expresa big endian, ambos para Unicode de 16 bits. . 2A06 es el caracter arabigo 'teh'. Algo que he leido frecuentemente es que en Unicode, uno de los 2 bytes es nulo; recuerda que esto solo es cierto si estamos ante caracteres Unicode latinos. A tener en cuenta que la letra 'teh' tambien es el valor '95FE'x. . 0D 00 es retorno de carro. . 0A 00 es algo asi como fin de linea. Entonces, ¿el Unicode es de 2 bytes? Es lo que dicen la mayoria de los articulos sobre Unicode. Pero el consorcio Unicode indica que hay de 8, 16 y 32 bits, mas que de Unicode, de UTF [ref.5]. P.ej.: '61'x = 'a' [UTF-8 (y UTF-7)] '0061'x = 'a' [UTF-16] '00000061'x = 'a' [UTF-32] ¿UTF? Si, UCS Transformation Format. ¿UCS? Si, Universal Character Set o ISO 10646. ¿ISO? Si, International Organization of Standardization. ¿IOS? Pozzi. El UTF evita el uso de codigos Unicode reservados. Es por ello que aunque la letra arabe 'teh' sea en Unicode el valor '062A'x, en UTF-8 acaba siendo 'D8AA'x: 11xxxxxx 10xxxxxx --> mascara UTF-8 [consulta ref.5] 011000 101010 --> valor binario del codigo Unicode de 'teh' (062A) ----------------- + 11011000 10101010 --> valor binario del valor UTF de 'teh' D8 AA --> valor hexadecimal del valor UTF de 'teh' * * * El estandar Unicode aporta una serie de algoritmos interesantes: - de ordenacion [UCA o Unicode Collation Algorithm], o sea, lo que ocurre cuando haces un ORDER BY de SQL. ¿Como se ordena alfabeticamente las letras chinas o arabes? ¿Y si hay registros en chino y en espa=ol a la vez? - de compresion [SCSU o Standard Compression Scheme for Unicode]: todo un mundo el de las compresiones. - de bidireccionalidad [BIDI]: mi favorito. 06.Algoritmo BIDI ----------------- La escritura arabe y la hebrea tienen un comportamiento comun [toda una metafora :| ] y es que se escriben de derecha a izquierda. Para permitirlo, existe el algoritmo BIDI, que produce un fascinante comportamiento en los textos en edicion para esas escrituras. Observa tu mismo como funciona. Primero escojamos un programa que permita editar en Unicode. Por ejemplo, la edit control de busqueda del Google desde IE 5.5 o MF 0.9. Pega una sola letra arabe en la celda de edicion. Se tendria que pegar sin problemas: en arabe. Ademas el cursor parpadeante tiene que haber quedado a la izquierda de la letra. Es curioso. Pega mas veces la misma letra, unas veces con espacios entre medio y otras sin ellos. ¡No siempre se pega lo mismo! El algoritmo es lo suficientemente listo como para aplicar la siguiente norma linguistica referente a las ligaturas de letras arabes: Una letra arabe puede escribirse en cuatro formas diferentes, segun se escriba aislada, como letra final de una palabra, entre otras 2 letras, o como letra inicial de una palabra. Si tienes nociones de arabe esto tambien te habra resultado fascinante. Ahora escribe letras latinas, numeros o simbolos aritmeticos. El cursor se situa en una posicion u otra y el sentido de escritura es de dcha. a izqda. o de izqda. a dcha., todo ello segun lo que vas escribiendo [contextual]. Esto es util para escribir en la misma frase palabras arabes y latinas, o escribir numeros y simbolos mientras escribes en arabe [aunque el arabe se escriba al reves que el espa=ol, el numero 1234 no es el 4321, sigue siendo el 1234]. Tambien el comportamiento de la seleccion de texto o del avance del cursor esta alterado. No se vosotros, pero yo lo encuentro fantastico!! Ved el codigo en ref.5. Hay alternativas al BIDI de Unicode(TM), como el FriBidi, el PGB [no, no es el Partido de la Gente del Bar, es el Pretty Good Bidi Algorithm] y el JavaBidi de IBM. 07.Sets en navegadores ---------------------- Ahora que tenemos algunas nociones sobre los sets, veamos como pueden ser representados en los navegadores de Internet. A nadie le habra pasado inadvertido el gigantesco menu de codificaciones que suelen ofrecer los navegadores de Internet: 18 en Netscape Comunicator 4.5, 30 en Internet Explorer 5.5 y 79 en Mozilla Firefox 0.9. Desde el vietnamita hasta el turco pasando por el hebreo y el chino simplificado... Los .htm a los que estamos acostumbrados suelen tener el meta tag referente al charset, de forma que el navegador seleccionara ese alfabeto. Los mas comunes por aca son: Pero estos impiden mostrar la mayoria de caracteres no latinos. P.ej. la letra arabe 'teh' Unicode aparecera como un interrogante. En el html esa letra arabiga se puede escribir de 3 formas para mostrarse con el aspecto esperado: - directamente si lo permite el editor de html. - mediante NCR's: P.ej. '

ت

'. Ese numero es el valor Unicode (062A) expresado en forma decimal. - mediante la codificacion UTF-8 directamente. P.ej. '

ت

' (xD8AA). , y siempre que el charset haga referencia al UTF [ref.6]: Tambien se puede codificar en Java [\u062A] o en Javascript [%u062A]. Como observacion, en una TextArea de una applet java (JDK 1.1.8, estoy anticuado, lo se) no hay ni ligatura de letras arabes ni bidireccionalidad. Ademas, las edit control (como las de contrase=a) se comportan de forma independiente al meta tag charset. Asi pues, IE 5.5 o MF 0.9 admiten caracteres arabes en la edit control aunque el charset no sea el UTF-8. Y otros como NC 4.5 no lo admiten en ningun caso (y aparecen interrogantes en vez de letras no latinas). 08.Passwords y Unicode ---------------------- Veamos ahora como la codificacion Unicode repercute en la seguridad de nuestras passwords, para bien y para mal. Generalmente cuando escribimos una password en Windows esta queda ocultada bajo asteriscos. P.ej. gracias al input type="password" de javascript, o al estilo ES_PASSWORD de un edit control de la API Win32, o a la clase TextField (AWT) de Java. Si la password esta asteriscada, el desasteriscador que la desasterisque buen desasteriscador sera. El primero que he encontrado por Internet es el Asterisk Key [AK]. Los desasteriscadores suelen basarse en quitar el flag ES_PASSWORD, por ejemplo lanzando lo siguiente contra todas las ventanas 'hijas' de la clase 'edit': SendMessage(GetDesktopWindow(),EM_SETPASSWORDCHAR,0,0); , o leer lo que haya en ellas con GetWindowText [ref.22]. La ayuda de AK dice que 'Multilingual passwords are supported'. ¿Seguro? Por ejemplo, vayamos a la pagina de correo de Yahoo y escribamos en el campo de contrase=a letras y numeros. Si tienes abierta la pagina web, el AK es capaz de detectarlo y de devolverte la password ocultada bajo asteriscos sin problemas. Ahora pongamos de password caracteres que lleven acentos o la e=e. El AK sigue sacando la password facilmente. Ahora pon de password letras arabes (con copiar y pegar); observa que se dan signos del algoritmo BIDI. Pero... prrrtz!!! El AK devuelve interrogantes, uno por cada caracter no ASCII. Si pegamos las mismas letras arabes en la edit control de usuario, la ausencia de asteriscos nos dejara ver dichas letras arabes. Por tanto, supongo que hay que entender 'multilingual' referido a que el AK soporta lenguas romanicas, germanicas, euskera y poquito mas. El AK tambien devuelve los interrogantes en el caso de pegar caracteres arabes en la casilla de password del Norton Antivirus, del Winzip 7.0 y en la de Project de Word ['Herramientas -> Macro -> Editor de Visual Basic -> Herramientas -> Propiedades de Project -> Proteccion']. Pero en estos casos hay un detalle importante: no se dan signos de bidireccionalidad cuando se pegan caracteres arabes. ¿Realmente estamos pegando letras arabes? Si corremos el recuperador de passwords de Winzip Zip Password 5.0, este nos recupera interrogantes. Entonces, ¿la funcion de copiar y pegar no funciono correctamente porque la edit control de Winzip no soportaba Unicode, y pusimos interrogantes como password creyendo que se pegarian letras arabes? Es posible. De hecho, seguro que las passwords de muchos miles de personas que utilizan lenguas no latinas son simples interrogantes :O, por falta de soporte al Unicode de los programas y por los asteriscos. Pero no es tan sencillo, ya que podria haber sido el propio Zip Password el que no soportara el Unicode. De hecho, eso ocurre con algunos recuperadores de passwords de Word y Excel. Veamos algunos ejemplos: 08.1.Passwords en Word ---------------------- Me refiero a Word v8.0. Puedo introducir una password a traves del copiar y pegar de letras o palabras, incluso escritas en arabe. En nuestro caso, una sencillita como la letra 'teh' [U+062A]. ¿Donde? En 'Herramientas -> Opciones -> Guardar -> Contrase=as'. Aceptar. Pide confirmacion, pues se la meto de nuevo, sin vaselina. Aceptar. Parece que le ha gustado. Observa que al introducir esa contrase=a se dan signos del algoritmo BIDI, con lo que podemos estar seguros de haber metido letras arabes. Y ahora a por algunos recuperadores [demos], por orden alfabetico [alfabeto latino, claro]: 1) AOXPPR 2.42 de ElcomSoft Me permite a=adir caracteres en hexa en la celda 'Custom Charset'. Si no a=ado expresamente '2A06', la contrase=a en hexa, no la encuentra. Si la a=ado, tarda pocos milisegundos en recuperarla. Excelente. 2) Guaranteed Word 97/2000 Decryptor v.1.3 beta de PSW-soft. Una demo en modo consola que solo permite crackear passwords 'nyxo'. No, no es un tecnicismo, es la password a crackear, con lo que no podemos hacer la prueba. Su ayuda asegura que tolera todo tipo de sets de caracteres. 3) Word Key Demo 6.3 de Passware La edit control de los caracteres a utilizar en el ataque por fuerza bruta permite el 'paste' de caracteres arabes copiados de otro sitio, y la password la saca en muy poco tiempo. Excelente. 4) WordPassword DEMO v5.0 de LastBit Software He probado todas las opciones de la demo y no se hacer que me recupere la contrase=a. Dispone de una opcion para seleccionar el set de caracteres [code page], como el 1256 Arabic, lo cual sugiere que si que la puede recuperar, pero no lo he conseguido. Sin calificar. 5) Word Password Recovery v1.0g de Intelore software No saca la password y no tiene pinta de que la pueda sacar. Admite como mucho los caracteres del ASCII extendido. Suspendido. 6) Word Recovery 2003 demo de Password Service Esta demo exige que la password empiece por 'zz'. Asi que en vez de la letra 'teh', pondremos 'zz[teh]'. Los sets de caracteres no admiten mas que el ASCII y poco mas. Suspendido. 08.2.Passwords en Excel ----------------------- Hablamos de Excel97. Para introducir una password podemos ir a la opcion 'Herramientas -> Proteger'. Le enchufamos de password el mismo caracter arabe de antes: la letra 'teh'. Confirmamos y parece que chuta. No obstante, advierte que 'la contrase=a contiene caracteres acentuados o ciertos signos de puntuacion que no se transferiran correctamente a Microsoft Excel para Macintosh'. Pues vale. Para los .xls, Lastbit Software tiene a ExcelPassword DEMO v5.0. Esta version advierte que para sacar ese tipo de passwords he de comprar la version entera. Identica advertencia de Excel Key Demo 6.3, que almenos admite caracteres en arabe en la edit control de 'Symbol set -> Custom', lo cual sugiere que es capaz de recuperarla. AOXPPR 2.42 de ElcomSoft me devuelve BL9. Eso son 3 caracteres, y yo puse solamente uno. El caso es que sirve tanto si metes el caracter 'teh' como si metes 'BL9'. En dos palabras: noacabo dentenderlo. Veamoslo en hexa y a camara lenta: 'BL9' ('424C39'x) = 'teh' ('2A06'x) Otros ejemplos: '123' = '123'; 'a' = 'a'; '[alfa]' = 'a'; 'aa' = 'aa'; '[alfa]' + 'a' = 'Aq'; 'a' + '[alfa]' = 'Aq'... absurdo!!!? ¿Alguien podria explicar que algoritmo se utiliza? 08.3.Conclusiones sobre passwords --------------------------------- Inicialmente pensaba que seria posible pegar caracteres arabes o chinos en una edit control de contrase=a para asi ser irrecuperable por las actuales herramientas de crackeo. O incluso poner una password en Times New Roman 14 y que fuera diferente de la misma pero en Arial 12. Esto ultimo hoy por hoy es algo descabellado viendo como funcionan los sets de caracteres, las fuentes y las edit controls. Pero escribirla con Unicode puede ser util. Una password Unicode es mas dificil de sacar que una password ASCII, porque las combinaciones con las que podemos hacer passwords son muchas mas (y el tiempo en reventarla, mayor). Ademas, palabras como las arabes no aparecen en los diccionarios tipicos de crackeo. Y los keyloggers de poco serviran si no tienen en cuenta el teclado que estamos utilizando. Ademas, los caracteres atipicos son dificiles de comunicar, lo cual es una ventaja frente a la Ingenieria social. Podriamos a=adirlo a la tipica checklist para passwords, recuerdo: utilizar simbolos y no solo letras, alternar mayusculas y minusculas, evitar que coincida con palabras reales o con conceptos que se relacionen con nuestro entorno, cambiarla cada poco tiempo... Pero solo si lo soporta el programa que nos pide la password. Si el programa no lo soporta, podemos estar escribiendo interrogantes como password sin darnos cuenta, y eso lo saca hasta el pato Donald. Igualmente, ya hay recuperadores que han previsto el Unicode. Una curiosidad mas, si googleais 'passwords en arabe' apareceran multitud de paginas porno. ¿Alguien lo entiende? 09.Portapapeles --------------- En todos los ejemplos hemos utilizado el copiar y pegar de letras arabes, que es una opcion valida siempre que origen y destino soporten Unicode. Supongo que se puede escribir directamente en arabe si se instalan y se activan los locales y drivers correspondientes en la maquina [National Language Support API y MultiLingual API] [ref.7]. Ahora comentare un par de comportamientos extra=os que he encontrado con la API de copiar y pegar, simplemente por el hecho de comentarlos. 1) Parece ser que la conversion automatica de CF_UNICODETEXT -> CF_TEXT de la API, segun la ref.3 no esta contemplada en mi Windows98: Clipboard Format Conversion Format Platform Support ---------------- ----------------- ---------------------- CF_OEMTEXT CF_TEXT Windows NT, Windows 95 CF_OEMTEXT CF_UNICODETEXT Windows NT CF_TEXT CF_OEMTEXT Windows NT, Windows 95 CF_TEXT CF_UNICODETEXT Windows NT CF_UNICODETEXT CF_OEMTEXT Windows NT CF_UNICODETEXT CF_TEXT Windows NT x? Sin embargo, puedo copiar y pegar 'letras' Unicode en los programas de Office-97, IE, o en WordPad. Eso es porque son programas Unicode con acceso directo a todos los caracteres en todos los sets soportados en una fuente. Si copio el caracter Unicode 'teh' de un .htm, y lo pego en el WordPad, muestra la letra 'teh' correctamente. Lo extra=o es que si miro con un visor hexadecimal ese mismo .txt, veo que hay '3F'x, o sea, un interrogante. Pero no veo un interrogante, yo estoy viendo una 'teh'!! Al cerrar WordPad y volver a abrirlo, aparece el interrogante que detectaba el visor hexadecimal. ¿Alguien sabe como la GDI me llega a mostrar lo que no hay? 2) Si copio una simple letra (arabe o no) de un .doc y lo pego en el FrontPage Express v2, aparecera algo como esto: {\rtf1\ansi\ansicpg1252\uc1 \deff0\deflang1033\deflangfe3082{\fonttbl{\f0\ froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f 2\fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;} {\f 16\froman\fcharset238\fprq2 Times New Roman CE;}{\f17\froman\fcharset204\f prq2 Times New Roman Cyr;}{\f19\froman\fcharset161\fprq2 Times New Roman G reek;}{\f20\froman\fcharset162\fprq2 Times New Roman Tur;} {\f21\froman\fc harset186\fprq2 Times New Roman Baltic;}{\f28\fmodern\fcharset238\fprq1 Co urier New CE;}{\f29\fmodern\fcharset204\fprq1 Courier New Cyr;}{\f31\fmode rn\fcharset161\fprq1 Courier New Greek;}{\f32\fmodern\fcharset162\fprq1 Co urier New Tur;} {\f33\fmodern\fcharset186\fprq1 Courier New Baltic;}}{\col ortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0 \green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green2 55\blue0;\red255\green255\blue255; \red0\green0\blue128;\red0\green128\blu e128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red 128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\st ylesheet{\nowidctlpar\widctlpar\adjustright \f2\fs18\lang1027\cgrid \snext 0 Normal;}{\*\cs10 \additive Default Paragraph Font;}}\margl1701\margr1701 \margt1417\margb1417 \deftab708\widowctrl\ftnbj\aenddoc\hyphhotz425\formsh ade\pgbrdrhead\pgbrdrfoot \fet0\sectd \linex0\headery709\footery709\colsx7 09\endnhere\sectdefaultcl {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{ \*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pn lcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5 \pndec\pnstart1 \pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\p nindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnin dent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pninde nt720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent 720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \nowidctlpar\widctlpar\adjust right \f2\fs18\lang1027\cgrid {\lang1034 \u1578\'3f}} Se trata de otro cruce de cables de las funciones de 'copiar y pegar'. No aparece en FPE v4. Esas lineas son texto con codificacion RTF. [Ref.18:] El RTF [Rich Text Format] es un metodo de codificacion de textos y graficos para ser transferidos entre Windows, MS-DOS y Macintosh. Admite los sets de caracteres ANSI, OEM 850 y 437 [es el OEM tipico de los USA], y Apple Macintosh, y como no, Unicode. Posee un monton de controles que me recuerda un lenguaje de tags, como el html, y entre ellos... si, ke pesao, hay controles de bidireccionalidad. Si creais un archivo de texto y lo guardais como 'texto RTF', y despues lo observais con un visor hexadecimal, vereis que es muy parecido a las lineas de antes. En concreto, el '\u1578' que aparece en la ultima linea es nuestra querida letra teh (U+062A). 10.Compilando Unicode en Windows -------------------------------- Hemos visto que hay aplicaciones que soportan Unicode y otras que no. Tambien parece haber compiladores que lo contemplan y otros que no. Yo normalmente compilo C con el lcc-Win32, y no he encontrado ninguna referencia para poder compilar un programa Unicode. Tampoco el djgpp parece soportarlo. Aunque las librerias graficas Allegro [ref.14] si que tratan muy bien los diferentes sets, Unicode incluido, incluso si se compila con el djgpp. Un ejemplo es el exunicod.c que trae en su bateria de ejemplos. Tambien distinguen Unicode las includes del viejo Borland C++ Compiler 5.5, pero hace siglos que no lo utilizo, y ya no se ni como funciona... Uno de mis preferidos, el Dev-C++ v4.0 [Mingw32] si que lo contempla en sus propias librerias, y es el que he utilizado. Por ejemplo, si observamos su include tchar.h, veremos que hay definiciones por duplicado, unas para Unicode y otras para no-Unicode [ANSI]: /* Non-unicode (standard) functions [las de toda la vida] */ #define _tprintf printf #define _tcscpy strcpy #define _tcslen strlen /* Unicode functions */ #define _tprintf wprintf #define _tcsncpy wcsncpy #define _tcslen wcslen Ademas casi todas las funciones estan definidas por duplicado, teniendo una de ellas una 'W' final ['W' de wide char, o sea, Unicode]; por ejemplo las tipicas Boxes de alerta pueden codificarse de 2 formas: int WINAPI MessageBoxA(HWND,LPCSTR,LPCSTR,UINT); //para ANSI int WINAPI MessageBoxW(HWND,LPCWSTR,LPCWSTR,UINT); //para Unicode He podido compilar un programa Win32 Unicode con el Dev-C++ en Windows98. Para ello, hay que incluir al principio las siguientes definiciones: #define UNICODE //para que compile como Unicode #define _UNICODE //para que pueda acceder a tchar.h como Unicode #include //las funciones de Windows #include //para poder utilizar Unicode y ANSI a la vez #include //para los wide-char sets (Unicode): wchar_t , y utilizar las funciones con la 'W' final si se quiere trabajar con Unicode: MessageBoxW(NULL,L"Esto es Unicode",L"Unicode",0); , o concretar las funciones no-Unicode 'A' para evitar las asunciones que ahora hace el compilador [ahora asume las funciones 'W' por defecto]: MessageBoxA(NULL,"Esto no es Unicode","ANSI",0); Pero en mi Windows98 no conseguia superar la funcion inicial RegisterClassW, y nisiquiera podia recuperar el error con GetLastError, que me devolvia los interrogantes tan decepcionantes que vimos antes. Despues de navegar en diferentes foros de programacion para buscar la solucion, descubri dos cosas mas: - Una, que hay mucha gente con problemas para programar con Unicode, la mayoria en entornos de XML y Java, y tambien en C. Muchos son de origen indio, arabe y japones [la mayoria se quejan de los dichosos interrogantes y de las conversiones entre sets]. - La otra, que en Windows9x [yo tengo un maldito Windows98], hay que utilizar la MLU [Microsoft Layer for Unicode]. Asi que me la he bajado de la web de Microsoft. Basicamente es la unicows.dll [casualmente ya la tenia instalada en el directorio donde tengo el PGP 8.0 para Windows, y deduzco que a ella se refiere su ayuda cuando dice 'Significantly expanded Unicode support']. Este problema no tendria que darse con WindowsNT/2K/XP, que tienen como set de trabajo el Unicode, no el ANSI como los Windows95/98/ME. Si se observan los nombres de las funciones exportadas de las dll de los Windows, se puede comprobar que las funciones con la W final abundan mas en WindowsNT que en Windows9x. Para linkar el compilado con la unicows.dll podeis bajaros las librerias de la ref.15, en mi caso la libunicows.a para Mingw32 (las hay para otros compiladores GNU). Con esto, ya tenemos un programa Unicode estable. Podemos mostrar texto Unicode con 'MessageBoxW(NULL,L"Esto es Unicode",L"Unicode",0);' Pero una alerta como esta: 'MessageBoxW(NULL,L"Teh:\x2A06-\x062A",L"ok",0);' devuelve 'Teh:?-?' en vez de la dichosa letra arabe 'teh'. Una explicacion es que en Windows9x, las MessageBox utilizan el set que se ha asignado al sistema [o sea, segun la configuracion regional]. Como no tengo disponible la configuracion regional arabe tampoco puedo confirmarlo. Muy bien. Pues mostremos el texto con: 'TextOutW(hdc,200,200,L"Teh:\x2A06-\x062A",10);' Y aparece: 'Teh:l-l' (donde 'l' es como un rectangulo negro). No se si es culpa del Windows98 o si es que me faltan componentes arabes... * * * Para rizar el rizo, ademas de haber Windows que trabajan en Unicode y otros que no, y ademas de haber programas que soportan Unicode y otros que no, y ademas de haber compiladores que compilan programas Unicode o no, y otros compiladores que solo compilan programas no Unicode... resulta que tambien hay compiladores que compilan programas codificados en Unicode y otros compiladores que compilan programas codificados con los sets ASCII o ANSI tradicionales. Lo cualooo?? En vez de codificar 'call mi_funcion' es posible llegar a codificar 'xxx xxxxxxx' [imaginad que las equis fueran escritas en ruso, o en chino, o en hebreo]. Compiladores como el GoAsm y GoRc (para ensamblador Win32) lo soportan muy bien [ref.12]. Me lo he de creer, porque nuevamente mi Windows 98 me impide compilar ni un miserable HolaMundo Unicode. Esto puede ser del agrado de los programadores mas nacionalistas. Pero imaginate que no pudieras leer el codigo de un programa DPM (de pura magnificiencia) porque estuviera codificado por ejemplo en C++ ruso!! Ahora bien, hoy por hoy, hay lenguas muertas como el boustrophedon o el hebreo biblico que poseen peculiaridades que ni el Unicode es capaz de resolver, asi que codificar un programa en esas lenguas es todo un reto [y una gilipollez]. 11.Fuentes ---------- Una de las pocas formas que he encontrado para mostrar texto arabe en mi Windows98 con un programa en C, es utilizando la funcion TextOutW para mostrar texto ANSI por pantalla, y seleccionando despues el alfabeto 'arabe' invocando al Dialogo de fuentes. Editores arabes como Minipad utilizan tambien una fuente arabe y asocian a cada glifo una tecla. Un simple 'copiar y pegar' nos hara ver que detras hay letras latinas. Una fuente es un set de caracteres con un dise=o comun utilizado para ser mostrado por pantalla o para ser impreso. Suelen tener la extension .FON (en fuentes 'raster' y 'vector') o las .FOT y .TTF (fuentes 'True Type'). Todas las fuentes utilizan un set de caracteres, de forma que proporcionan una imagen para cada codigo del set. Entiendo que al seleccionar una fuente y el alfabeto 'arabe', lo que hago es decirle al sistema que deje de mostrar los glifos asociados al ANSI 1252 y que pase a mostrar los del ANSI 1256. 12.Vaya mierda... ----------------- Hemos visto que la incompatibilidad de un programa o sistema con el Unicode nos puede fastidiar un poco: un interrogante no es ni sera nunca la letra arabe 'teh'. Segun la ref.5, estos interrogantes son el reflejo de la corrupcion de la informacion, producida al pasar datos en Unicode a una aplicacion que no lo soporta. Otras veces se ponen rectangulos negros o cuadraditos. Otras reacciones pueden ser omitir los caracteres irreconocibles. O poner lo mas parecido al caracter. Por ejemplo, el simbolo de 'menor', cuando nosotros pusimos el simbolo 'menor o igual', o quitar acentos, dieresis y similares. P.ej.: wchar_t miunicode[]=L"\x0143-\x0144-\x0145-\x0146-\x0147-\x0148"; //Diferentes 'enes' con acentos en diferentes posiciones MessageBoxW(NULL,miunicode, L"ok",0); //Devuelve 'N-n-N-n-N-n', lo cual es inexacto. Y con valores superiores //empiezan a aparecen los interrogantes (Windows9x). TextOutW(hdc,200,200,miunicode,50); //Muestra rectangulos negros (Windows9x). Del incorrecto reformateo no se libra el flujo de informacion de la red. Por ejemplo, consulta alguna web japonesa o china sin tener los componentes y/o codificaciones adecuados. Y tampoco se libra la informacion sensible. P.ej. en la ref.8 se comenta la corrupcion que sufre una password segun se envie o se reciba en ANSI o en Unicode y teniendo en cuenta su longitud, siendo los culpables los bytes nulos iniciales y/o finales, que en unos casos se tienen en cuenta y en otros no. En otra referencia de la que no he guardado copia, un administrador se quejaba de que muchas de las passwords de loggin de sus clientes aparecian en la base de datos como interrogantes. [Ese administrador es un fisgon!!] Comentar tambien que toda corrupcion de datos podria ser 'explotable'. No tratare de exploits, materia de la que no tengo NPI [nociones para implementarlo]. Solo recordare al famoso exploit del Unicode en servidores IIS [ref.17], y advertir que se esta poniendo de moda los exploits compatibles con Unicode para no quedarse anticuados [p.ej. refs.21, 11 y 16]. Tambien hay posturas criticas a nivel linguistico, que es la razon de ser del Unicode. Navegando por paginas de otros paises (japonesas, armenias, indias...), me he dado cuenta de que por alla ponen a parir al Unicode como por aca se pone a parir a Microsoft. Bueno, no tanto. Le sacan defectos por todas partes!! Tambien ponen a parir algunos sets ISO que se autodenominan 'multilingues'. Y lo afirman con conocimiento de causa (ellos son quienes utilizan sus escrituras, no nosotros): - Caracteres de un mismo alfabeto dispersos en la escala Unicode. - Caracteres de un alfabeto en orden diferente al especificado por los protocolos autoctonos de esa lengua. Eso corrompe las ordenaciones. - Caracteres de un alfabeto que son caracteres restringidos de lenguajes de programacion y que no tienen un codigo diferente (p.ej. el punto y coma). - Insuficiente soporte para procesar escrituras contextuales basadas mas en reglas linguisticas y foneticas que en simples transcripciones graficas. Y ademas no tiene licencia GNU. 13. ...tan buena ---------------- Sin embargo, hay que tener en cuenta que casi todo el tercer mundo esta en vias de desarrollo, y por tanto en vias de desarrollarse en Internet. Tarde o temprano Internet se inundara de paginas en arabe, chino y swahili. Esos alfabetos son utilizados por mas poblacion que la que hoy en dia tiene acceso facil a Internet. Para saber de primera mano que piensan esas personas, han de poderse expresar en sus lenguas maternas; tambien se haran necesarios traductores y conversores universales. Para ambas cosas hemos de disponer de algo como el Unicode. De otra forma, cada nuevo set de caracteres obliga a crear cientos de algoritmos para realizar conversiones a los sets preexistentes. Se hace necesario un set universal definitivo, y el Unicode-UTF va camino de serlo. Un area del conocimiento que promete ser una panacea es la Linguistica Computacional, que trata de los traductores, 'resumidores', buscadores inteligentes, transcriptores, reconocedores foneticos, interpretes de manuscritos, contestadores de preguntas y otras maravillas de la ciencia ficcion que poco a poco estan entrando en nuestras vidas. Algo como el Unicode es mas que basico para implementar eso. Por tanto, si sois programadores estais moralmente obligado a tener todo este rollo en cuenta [segun mi moral, claro]. 14.Despedida ------------ Y nada mas por hoy. Espero que os haya gustado menos que el siguiente articulo que escriba. Saludos a tod@s ;) 15.Principales referencias -------------------------- [1] - Contrase=as en Windows, de H.M.Racciatti, 2002; Raregazz 19. [2] - http://www.webopedia.com [3] - Microsoft® Win32® Programmer's Reference, 1992-1996. [5] - http://www.unicode.org [6] - http://www.alanwood.net/unicode [7] - http://www.aramedia.com/ms2000/win2000.htm [8] - http://lists.samba.org/archive/samba-technical/2003-March/027728.html [9] - http://tdil.mit.gov.in/standard.htm [10]- http://shlimazl.nm.ru/eng [11]- Creating Arbitrary Shellcode in Unicode Expanded Strings; Anley 2002. [12]- http://www.GoDevTool.com [13]- http://msdn.microsoft.com/library [14]- http://alleg.sourceforge.net [15]- http://libunicows.sourceforge.net [16]- Building IA32 'Unicode-Proof' Shellcodes (obscou, phrack 61 - 0x0b). [17]- Microsoft IIS Unicode Exploit; Nate Miller 2001. [18]- http://www.biblioscape.com/rtf15_spec.htm [19]- http://www.i18ngurus.com/docs/992966406.html. [20]- http://tronweb.super-nova.co.jp [21]- Writing UTF-8 compatible shellcodes (greuff, phrack 62 - 0x09). [22]- http://www.codeguru.com/Cpp/controls/editctrl/passwordsandsecurity agosto-2004 *EOF*