diff options
author | FreeArtMan <dos21h@gmail.com> | 2021-05-27 20:06:47 +0100 |
---|---|---|
committer | FreeArtMan <dos21h@gmail.com> | 2021-05-27 20:06:47 +0100 |
commit | e63ed8a651e5246f8698a9c1c3e540029710d0e9 (patch) | |
tree | cfd58d80345f17dc9f458bad88181811a89b3592 | |
parent | 9b9586b559edb387af804c52d2b593b711ce98be (diff) | |
download | md-content-e63ed8a651e5246f8698a9c1c3e540029710d0e9.tar.gz md-content-e63ed8a651e5246f8698a9c1c3e540029710d0e9.zip |
Update 10 articles from html to md
-rw-r--r-- | md/writeup.md | 20 | ||||
-rw-r--r-- | md/writeup/avr_disassembler.md | 67 | ||||
-rw-r--r-- | md/writeup/avr_echo.md | 36 | ||||
-rw-r--r-- | md/writeup/basic_http_server.md | 30 | ||||
-rw-r--r-- | md/writeup/blender_scripts.md | 20 | ||||
-rw-r--r-- | md/writeup/c_bin2hex.md | 18 | ||||
-rw-r--r-- | md/writeup/c_c11_standard_generic_keyword.md | 104 | ||||
-rw-r--r-- | md/writeup/c_inline_assembler.md | 105 | ||||
-rw-r--r-- | md/writeup/dwm_desktop_environment.md | 64 | ||||
-rw-r--r-- | md/writeup/wraping_c_plus_plus_exceptions_templates_and_classes_in_c.md | 236 | ||||
-rw-r--r-- | md/writeup/x11_prototype_gui.md | 2 |
11 files changed, 691 insertions, 11 deletions
diff --git a/md/writeup.md b/md/writeup.md index fa9b397..25a0883 100644 --- a/md/writeup.md +++ b/md/writeup.md @@ -68,17 +68,17 @@ title: Writeup page [Linux antidebug 3](writeup/linux_antidebug_3.md) [Linux antidebug 4](writeup/linux_antidebug_4.md) [Linux antidebug 5](writeup/linux_antidebug_5.md) +[C C11 standard _Generic keyword](writeup/c_c11_standard_generic_keyword.md) +[C inline assembler](writeup/c_inline_assembler.md) +[Wrapping C++ exceptions, templated and classes in C](writeup/wraping_c_plus_plus_exceptions_templates_and_classes_in_c.md) +[Makefile tips](writeup/makefile_tips.md) +[AVR disassembler](writeup/avr_disassembler.md) +[AVR echo](writeup/avr_echo.md) +[Basic HTTP server](writeup/basic_http_server.md) +[Blender Scripts](writeup/blender_scripts.md) +[C Bin2Hex](writeup/c_bin2hex.md) +[DWM desktop environment](writeup/dwm_desktop_environment.md) -[C C11 standart _Generic keyword](http://archive.main.lv/writeup/c_c11_standart__generic_keyword.html) -[C inline assembler](http://archive.main.lv/writeup/c_inline_assembler.html) -[Wrapping C++ exceptions, templated and classes in C](http://archive.main.lv/writeup/wrapping_c___exceptions,_templated_and_classes_in_c.html) -[Makefile tips](http://archive.main.lv/writeup/makefile_tips.html) -[AVR disassembler](http://archive.main.lv/writeup/avr_disassembler.html) -[AVR echo](http://archive.main.lv/writeup/avr_echo.html) -[Basic HTTP server](http://archive.main.lv/writeup/basic_http_server.html) -[Blender Scripts](http://archive.main.lv/writeup/blender_scripts.html) -[C Bin2Hex](http://archive.main.lv/writeup/c_bin2hex.html) -[DWM desktop environment](http://archive.main.lv/writeup/dwm_desktop_environment.html) [Assembler calculate polynom](http://archive.main.lv/writeup/assembler_calculate_polynom.html) [CVE 2010-1160 Exploiting nano](http://archive.main.lv/writeup/cve_2010-1160_exploiting_nano.html) [ELF rewrite function](http://archive.main.lv/writeup/elf_rewrite_function.html) diff --git a/md/writeup/avr_disassembler.md b/md/writeup/avr_disassembler.md new file mode 100644 index 0000000..1ac88a9 --- /dev/null +++ b/md/writeup/avr_disassembler.md @@ -0,0 +1,67 @@ +title:Notes on videos +keywords:math,statistics + +# AVR disassembler + + +```text +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++ AVR dissasembler + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++ INDEX + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1. Intro + 2. Example + 3. Usage + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++ 1.Intro + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + +Disassembler for Atmel AVR microcontrollers made for be fast and simple. No +extra features only basicss. Converts binary file to AVR asm output. + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++ 2.Example + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Here is example output +2411 CLR 0x11 +be1f OUT 0x3f , 0x1 +e5cf LDI 0xc , 0x5f +e0d4 LDI 0xd , 0x4 +bfde OUT 0x3e , 0x1d +bfcd OUT 0x3d , 0x1c +e010 LDI 0x1 , 0x0 +e6a0 LDI 0xa , 0x60 +e0b0 LDI 0xb , 0x0 +ebee LDI 0xe , 0xbe +e0f0 LDI 0xf , 0x0 +c002 RJMP +4 +9005 LPM 0x0 +920d ST 0x0 , 0x0 +36a0 CPI 0xa , 0x60 +07b1 CPC 0x1b , 0x11 +f7d9 BRBC 0x1 , -10 +e010 LDI 0x1 , 0x0 +e6a0 LDI 0xa , 0x60 +e0b0 LDI 0xb , 0x0 +c001 RJMP +2 + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++ 3.Usage + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +disavr file.bin file.asm +``` + +### Links +https://github.com/FreeArtMan/dis_avr/ + + +## Downloads +dis_avr0.1.zip +10KiB - http://archive.main.lv/files/writeup/avr_disassembler/dis_avr0.1.zip
\ No newline at end of file diff --git a/md/writeup/avr_echo.md b/md/writeup/avr_echo.md new file mode 100644 index 0000000..0dac9fb --- /dev/null +++ b/md/writeup/avr_echo.md @@ -0,0 +1,36 @@ +title:AVR echo +keywords:avr,echo,c,atmega + + +# AVR echo +This code tested on ATmega16 + +```c +#include <avr/io.h> + +#define FOSC 16000000UL +#define BAUD 9600 +#define MYUBRR FOSC/16/BAUD-1 + +void USART_Init( unsigned int ubrr) +{ + UBRRH = (unsigned char)(ubrr>>8); + UBRRL = (unsigned char)ubrr; + UCSRB = (1<<RXEN)|(1<<TXEN); + UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0); +} + +int main() +{ + char c; + USART_Init( MYUBRR ); + while(1) + { + while ( !(UCSRA & (1<<RXC))){}; + c = UDR; + while (!(UCSRA & (1<<UDRE))){}; + UDR = c; + } + return 0; +} +``` diff --git a/md/writeup/basic_http_server.md b/md/writeup/basic_http_server.md new file mode 100644 index 0000000..cd1b4de --- /dev/null +++ b/md/writeup/basic_http_server.md @@ -0,0 +1,30 @@ +title:Basic HTTP server +keywords:c,http,server + +# Basic HTTP server +Basic HTTP server. When you type url it shows listing of your local directory. If you tipe with path to file name noting hapens +Use: +``` +http://*.*.*.*:<port>/ -> disk start directory +http://*.*.*.*:<port>/home/ -> home directory +``` +Run: +``` +./server [port] +``` + +Compile: +``` +gcc server.c -o server +``` + +Here is also python source. It runs on port:8081 and prints in terminal HTTP request. You can see what browser sends to server. + +## Downloads +servpy.zip - +1KiB - http://archive.main.lv/files/writeup/basic_http_server/servpy.zip +serverc.zip - +2KiB - http://archive.main.lv/files/writeup/basic_http_server/serverc.zip + + + diff --git a/md/writeup/blender_scripts.md b/md/writeup/blender_scripts.md new file mode 100644 index 0000000..8f08f77 --- /dev/null +++ b/md/writeup/blender_scripts.md @@ -0,0 +1,20 @@ +title:Blender Scripts +keywords:blender,python,scripting,fractal,koh + +# Blender Scripts +Here some old blender scripts with looks that dont +work for newest versions of blender + + +## Downloads +blender-towers.zip - +1KiB - http://archive.main.lv/files/writeup/blender_scripts/blender-towers.zip +towers.py.zip - +1KiB - http://archive.main.lv/files/writeup/blender_scripts/towers.py.zip + +## Images + +<a href=/img/blender/16.jpg width="250"><img src="http://main.lv/img/blender/16.jpg" style="width:40%" alt="blender fractal"></a> +<a href=/img/blender/18.jpg width="250"><img src="http://main.lv/img/blender/18.jpg" style="width:40%" alt="blender fractal"></a> +<a href=/img/blender/5.jpg width="250"><img src="http://main.lv/img/blender/5.jpg" style="width:40%" alt="blender fractal"></a> +<a href=/img/blender/19.jpg width="250"><img src="http://main.lv/img/blender/19.jpg" style="width:40%" alt="blender fractal"></a>
\ No newline at end of file diff --git a/md/writeup/c_bin2hex.md b/md/writeup/c_bin2hex.md new file mode 100644 index 0000000..441a115 --- /dev/null +++ b/md/writeup/c_bin2hex.md @@ -0,0 +1,18 @@ +title:C Bin2Hex +keywords:c,binary,hex + +# C Bin2Hex +Converts binary file to hex file. + +Use: +``` +./bin2hex [bin_file] - for local output + +./bin2hex [bin_file] [hex_text_file] - for file output +``` + + +### Downloads +abin2hex.tar.gz - +1KiB - http://archive.main.lv/files/writeup/c_bin2hex/abin2hex.tar.gz + diff --git a/md/writeup/c_c11_standard_generic_keyword.md b/md/writeup/c_c11_standard_generic_keyword.md new file mode 100644 index 0000000..639264c --- /dev/null +++ b/md/writeup/c_c11_standard_generic_keyword.md @@ -0,0 +1,104 @@ +title:C C11 standart _Generic keyword +keywords:c,c11,generic + + +# C C11 standart _Generic keyword + +## INTRO + + +In C standart c11 is supported new keyword _Generic. It add way how +we can add at macro level decisitions about variable types. And now is +possible make some C++ like function "overloading". Here is some variants how +to use this generic "_Generic". Now could print variables dont looking +on its type _Generic will deal with it. + + +## EXAMPLES + +Detect type + +```c +#define type_str(T) _Generic( (T), int: "int",\ +long: "long",\ +default: "Unknown type") +``` + +Now we have define check for 2 types int and long. If there is some type +undefined then choose default type and print "Unknown type". This is auto +printf example where you can detect type and print its name. But as in page [1] +you can add number values and compare types in simple way. + +```c +printf("Type1 %s\n", type_str('a')); +printf("Type2 %s\n", type_str(1)); +printf("Type3 %s\n", type_str(1l)); +printf("Type4 %s\n", type_str(0.0f)); +``` + +Also is possible to use generic for 2 or more types but then amount +of declaration grows. But it means that now according to params +we can choose best function. + +```c +#define type_str2(T1,T2) _Generic( (T1),\ +int: _Generic((T2),int:"int int", default: "int UNK"),\ +default: "UNK UNK" ) + +printf("Double Type 1 %s\n", type_str2(1,1)); +printf("Double Type 2 %s\n", type_str2(1,0.0f)); +printf("Double Type 3 %s\n", type_str2(.0f,.0f)); +``` + +Check if types is compatible + + +Strange but some types could be invalid if there is const used, like +'int' and 'const int'. + +```c +#define is_compatible(x,T) _Generic((x), T:"compatible",\ +default: "non-compatible") +``` + +Here is defined 2 types and only (int and int) and (const int and const int) +is compatible. + +```c +int i1; +const int i2; +printf("int == int, %s\n", is_compatible(i1,int)); +printf("const int == const int, %s\n", is_compatible(i2,const int)); +printf("int == const int, %s\n", is_compatible(i1,const int)); +printf("const int == int, %s\n", is_compatible(i2,int)); +``` + + + +## TESTED + +gcc-4.9.1 +clang-3.4 + + +## FILES + +ex1.c - one argument generic +ex2.c - two argument generic +ex3.c - check for compatibility + + +## Links +http://www.robertgamble.net/2012/01/c11-generic-selections.html +http://en.wikipedia.org/wiki/C11_%28C_standard_revision%29 +https://gcc.gnu.org/wiki/C11Status + +## Downloads +ex3.c - +1KiB - http://archive.main.lv/files/writeup/c_c11_standart__generic_keyword/ex3.c +ex1.c - +1KiB - http://archive.main.lv/files/writeup/c_c11_standart__generic_keyword/ex1.c +ex2.c - +1KiB - http://archive.main.lv/files/writeup/c_c11_standart__generic_keyword/ex2.c +source.tar.gz - +1KiB - http://archive.main.lv/files/writeup/c_c11_standart__generic_keyword/source.tar.gz
\ No newline at end of file diff --git a/md/writeup/c_inline_assembler.md b/md/writeup/c_inline_assembler.md new file mode 100644 index 0000000..5566192 --- /dev/null +++ b/md/writeup/c_inline_assembler.md @@ -0,0 +1,105 @@ +title:C inline assembler +keywords:c,inline,assembler + + +# C inline assembler +There is long time since I wanted to learn "creepy" gcc inline assembly. +Looking at manuals its not so hard and "creepy". Using it is more +interesting and dissambly of compiled code is very nice looking. + +volatile puts our asm code where it is and don't optimize it without +volatile it can optimize. + +What to write in __asm__ directive looks like this + +```c +__asm__ __volatile__("our_code":output:input:used) +``` + +as code to convert to inline asm we will use last post [2]. + +There is only one instruction that we using and it usage was + +```c +get_timer: + rdtsc + ret +``` + +its not very optimal and for 1 instruction writing whole function +its not beautiful. We remember that returning result of this function is +saved in eax register. + +```c +__asm__ __volatile__("rdtsc":"=a"(x)::) +``` + +code looks like this. But we can make it as define function + +```c +#define get_timer(X) __asm__ __volatile__("rdtsc":"=a"(X)::) +``` + +This code works fine and give 70058 ticks on cycle +When adding option -O2 then result becomes wherry strange. + +As we remember that rdtsc return result in edx:eax then we add to +used registers(clobber) %edx. + +```c +#define get_timer(X) __asm__ __volatile__("rdtsc":"=a"(X)::"%edx") +``` + +And also we can rewrite everything as +inline function. + +```c +static inline unsigned int get_timeri() +{ + unsigned int i; + __asm__ __volatile__("rdtsc":"=a"(i)::); + return i; +} +``` + + +Now this two functions works fine with -O options. +When empty cycle is optimized then it becomes empty and resulting +tick number is 32 for both inline function and define macro. +It not working for his main purpose. When no optimization switched +then get_timer works for some ticks faster then get_timeri. + +We can add attribute always inline and we will win some ticks +and function will always inline regards optimization level + +```c +__attribute__((always_inline)) unsigned int get_timeri() +``` + +Too fix test cycle for our measurement we make it as object file +and it will compiled without options. + +```c +void fixed_cycle() +{ + int i; + for (i=0;i<10000;i++) + { + } +} +``` + +Now everything looks quite good and also inline assembly works as expected. + +For reference about inline asm you can go to [1] + + + +## Links +http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html + +## Downloads +asm_inline.zip - +3KiB - http://archive.main.lv/files/writeup/c_inline_assembler/asm_inline.zip +dis_avr0.1.zip - +10KiB - http://archive.main.lv/files/writeup/c_inline_assembler/dis_avr0.1.zip
\ No newline at end of file diff --git a/md/writeup/dwm_desktop_environment.md b/md/writeup/dwm_desktop_environment.md new file mode 100644 index 0000000..47a0951 --- /dev/null +++ b/md/writeup/dwm_desktop_environment.md @@ -0,0 +1,64 @@ +title:DWM desktop environment +keywords:dwm,pertag,pango,systemtray + +# DWM desktop environment + +## INTRO + +DWM is minimalistic tiling manager it contain only few thousand lines of +code. It main idea is to be simple as possible and usable as possible. +It has only minimal features and if you want to extend it you need to +edit dwm C source config file or add some patches from dwm project +web page. You dont need to use mouse to use dwm all actions can be done +with keyboard. + +## GOAL + +Make dwm fork with some useful minimalistic stuff like dwmstatus +program that show system statuses. And allow to switch on/off dwm +patches with linux kernel menuconfig(without menuconfig everything +works). +Next thing to add is some minimalistic screenlock, screensaver +and login. At then end there could be minimalistic "suckless" desktop +environment with all things needed. All parts are as separate +repositories and can be used independently. + +## CHANGELOG +### [2014.07.10] +dwmstatus +[+]add temperature status +[+]add current CPU usage status +[+]add battery/AC status + +### [2014.07.03] +dwm branch 6.0 +[+] added pango patch +[+] added systemtray patch +[+] added pertag patch +[+] menuconfig support +dwmstatus +[+] added time status +[+] added date status +[+] menuconfig support + + +## Links +http://dwm.suckless.org/ +http://dwm.suckless.org/dwmstatus/ +http://dwm.suckless.org/patches/ +https://github.com/FreeArtMan/dwm-fancy +https://github.com/FreeArtMan/dwmstatus-fancy +https://www.kernel.org/ +http://en.wikipedia.org/wiki/Menuconfig + +## Downloads +dwmstatus-fancy-0.1.tar.gz - +105KiB - http://archive.main.lv/files/writeup/dwm_desktop_environment/dwmstatus-fancy-0.1.tar.gz +dwm-fancy-0.1.tar.gz - +28KiB - http://archive.main.lv/files/writeup/dwm_desktop_environment/dwm-fancy-0.1.tar.gz + +## Images + +<a href=/img/dwm/dwm-0.1.png width="250"><img src="http://main.lv/img/dwm/dwm-0.1.png" style="width:40%" alt="dwm workspace"></a> +<a href=/img/dwm/dwm-fancy-0.1.png width="250"><img src="http://main.lv/img/dwm/dwm-fancy-0.1.png" style="width:40%" alt="dwm workspace"></a> +<a href=/img/dwm/dwmstatus-fancy-0.1.png width="250"><img src="http://main.lv/img/dwm/dwmstatus-fancy-0.1.png" style="width:40%" alt="dwm workspace"></a>
\ No newline at end of file diff --git a/md/writeup/wraping_c_plus_plus_exceptions_templates_and_classes_in_c.md b/md/writeup/wraping_c_plus_plus_exceptions_templates_and_classes_in_c.md new file mode 100644 index 0000000..0f43f21 --- /dev/null +++ b/md/writeup/wraping_c_plus_plus_exceptions_templates_and_classes_in_c.md @@ -0,0 +1,236 @@ +title:Wrapping C++ exceptions, templated and classes in C +keywords:c++,c,exeptions,templates,classes + +# Wrapping C++ exceptions, templated and classes in C + +Sometime some libraries is distributed only as C++ libs or in template +code. Or plug-ins for some programs is only in C or other language. + +Here can join C and C++ compiled code and there will no big difference +with language you use. Only need to choose right compiler for compilation. +C++ stuff can be easily hidden and you can use some C++ "only" features +in C without notice it. + +Use templates from C. + + +Templates is most C++'sh part of all. Templates are defined in C++ headers +and there not generate code. Only when you use they generate code. +It reason why cannot include them inside *.so or *.a libraries. +But you can always generated templates function examples that will +generate code. And it means it now can be inside *.so and *.a. +To use templates from C and compile it with C we need to hide C++ headers +from C and create templates generated code + +C compatible header code.h + +```c +extern float cmpx_add_f(float, float); +extern int cmpx_add_i( int, int ); +``` + +C++ template code.hpp + +```c +template <typename T> +inline T cmpx_add( T a, T b ) +{ + return a+b; +} +``` + +Tell C++ to generate code for specific templates code.hpp + +```c +template int cmpx_add<int>(int, int); +template float cmpx_add<float>(float, float); +``` + +Write C compatible wrapper in C++ + +```c +float cmpx_add_f( float a, float b ) +{ + return cmpx_add<float>(a,b); +} + +int cmpx_add_i( int a, int b ) +{ + return cmpx_add<int>(a,b); +} +``` + +lets see now object file info +``` +readelf -a +``` + +```c +18: 0000000000000000 63 FUNC GLOBAL DEFAULT 5 cmpx_add_f +20: 0000000000000000 42 FUNC WEAK DEFAULT 13 _Z8cmpx_addIfET_S0_S0_ +21: 000000000000003f 31 FUNC GLOBAL DEFAULT 5 cmpx_add_i +22: 0000000000000000 20 FUNC WEAK DEFAULT 12 _Z8cmpx_addIiET_S0_S0_ +``` + +We see that functions inside code.h is globally visible and we can use them +without problem from C. + +Use C++ exceptions + + +Exceptions is usually very C++'sh everyone know that exceptions cannot be +used in C. There is some C libraries that add some kind exceptions for +C. That libraries usually uses setjmp and longjmp for simulating that kind of stuff. + +C header + +```c +extern void raise_exception( int ); +``` + +C++ code for raising exceptions + +```c +extern void raise_exception( int a ) +{ + try + { + int b; + b = b/a; + printf("Everything ok ;]\n"); + } + catch ( int e ) + { + printf("Catching up exception number %d \n",e); + } +} +``` + +C use exceptions + +```c +raise_exception( 1 ); +raise_exception( 0 ); +``` + +Here is seen that C++ exception raises inside C code. There can be made +some code additions and C++ exceptions can be used in C with some tricks. +Not yet proof of concept. But with pointers to functions +(wasn't they called callbacks?) it cone be done. + +Use C++ classes + + +C completable headers + +```c +extern void* clA_init(); +extern void clA_add( void*,int, int ); +extern int clA_empty( void* ); +extern void clA_destroy( void* ); +``` + +C++ class definitions + +```c +class A +{ + public: + char *p; + A(); + ~A(); + void add( int, int ); + bool empty(); +}; +``` + +C++ class implementation + +```c +A::A() +{ + this->p = (char *)malloc(1024); +} + +A::~A() +{ + printf("Free Class Baby!!!\n"); + if (this->p != NULL) + { + free( this->p); + } +} + +void A::add( int a, int b ) +{ + int i = cmpx_add_i( a , b ); + printf("%d\n", i); +} + +bool A::empty() +{ + if (this->p == NULL) + { + return true; + } + else + { + return false; + } +} +``` + +C++ wrapping functions + +```c +extern void* clA_init() +{ + A *a = new A; + return (void *)a; +} + + +extern void clA_add( void *c, int a, int b ) +{ + A *cl=(A*)c; + cl->add( a, b ); +} + +extern int clA_empty( void *c ) +{ + A *cl=(A*)c; + bool b = cl->empty(); + if ( b == true ) + { + return 1; + } else + { + return 0; + } +} + +extern void clA_destroy( void *c ) +{ + A *cl = (A*)c; + cl->~A(); +} +``` + +It easy to give C++ class to C as void* and then use +C++ class functions (wasnt they called methods?) from C +simply as pointers. It segfault oriented but it the way how it works. + +These examples shows that you can stay as much as possible with C +and use C++ compiled code. + + +## Links +http://linux.die.net/man/1/readelf +http://gcc.gnu.org/codingconventions.html#ExternC +http://www.cplusplus.com/doc/tutorial/classes/ +http://linux.die.net/man/3/setjmp +http://linux.die.net/man/3/longjmp + +## Downloads +c_cpp_tricks.tar.gz - +2KiB - http://archive.main.lv/files/writeup/wrapping_c___exceptions,_templated_and_classes_in_c/c_cpp_tricks.tar.gz diff --git a/md/writeup/x11_prototype_gui.md b/md/writeup/x11_prototype_gui.md index 8576ce1..7b69094 100644 --- a/md/writeup/x11_prototype_gui.md +++ b/md/writeup/x11_prototype_gui.md @@ -35,7 +35,7 @@ http://www.x.org/wiki/ProgrammingDocumentation/ http://archive.main.lv/files/writeup/x11_prototype_gui/xlib_proto_gui.tar.gz -![GUI](/img/x11_gui/gui.png) +<a href=/img/x11_gui/gui.png width="250"><img src="/img/x11_gui/gui.png" style="width:40%" alt="GUI"></a> |