The Cairo graphics tutorial -------Cairo backends

本文介绍了如何使用Cairo库创建PNG、PDF、SVG文件及在GTK窗口中绘制文本,涵盖了多种输出格式的实现。

The Cairo library supports various backends. In this section of the Cairo graphics tutorial, we will use Cairo to create a PNG image, PDF file, SVG file and we will draw on a GTK window.


PNG image

In the first example, we will create a PNG image.

#include <cairo.h>

int main (int argc, char *argv[])
{
  cairo_surface_t *surface;
  cairo_t *cr;

  surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 390, 60);
  cr = cairo_create(surface);

  cairo_set_source_rgb(cr, 0, 0, 0);
  cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
      CAIRO_FONT_WEIGHT_NORMAL);
  cairo_set_font_size(cr, 40.0);

  cairo_move_to(cr, 10.0, 50.0);
  cairo_show_text(cr, "Disziplin ist Macht.");

  cairo_surface_write_to_png(surface, "image.png");

  cairo_destroy(cr);
  cairo_surface_destroy(surface);

  return 0;
}

This example is a small console application, that will create a PNG image.

 #include <cairo.h>

In this header file, we will find declarations of our functions and constants.

 cairo_surface_t *surface;
 cairo_t *cr;

Here we declare a surface and a Cairo context.

 surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 390, 60);
 cr = cairo_create(surface);

We create a surface and a Cairo context. The surface is an 390x60 px image.

 cairo_set_source_rgb(cr, 0, 0, 0);

We will draw in black ink.

 cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
      CAIRO_FONT_WEIGHT_NORMAL);
 cairo_set_font_size(cr, 40.0);

We choose a font type and set it's size.

 cairo_move_to(cr, 10.0, 50.0);
 cairo_show_text(cr, "Disziplin ist Macht.");

We move to a (10.0, 50.0) position within the image and draw the text.

 cairo_surface_write_to_png(surface, "image.png");

This function call creates the PNG image.

 cairo_destroy(cr);
 cairo_surface_destroy(surface);

In the end, we clean the resources.


PNG image
PNG image

PDF file

In the second example, we will use the Cairo library to create a simple PDF file.

#include <cairo/cairo.h>
#include <cairo/cairo-pdf.h>

int main() {

  cairo_surface_t *surface;
  cairo_t *cr;

  surface = cairo_pdf_surface_create("pdffile.pdf", 504, 648);
  cr = cairo_create(surface);

  cairo_set_source_rgb(cr, 0, 0, 0);
  cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
      CAIRO_FONT_WEIGHT_NORMAL);
  cairo_set_font_size (cr, 40.0);

  cairo_move_to(cr, 10.0, 50.0);
  cairo_show_text(cr, "Disziplin ist Macht.");

  cairo_show_page(cr);

  cairo_surface_destroy(surface);
  cairo_destroy(cr);

  return 0;
}

We must open the pdf file in a pdf viewer. Linux users can use KPDF or Evince viewers.

 surface = cairo_pdf_surface_create("pdffile.pdf", 504, 648);

To render a pdf file, we must create a pdf surface using the cairo_pdf_surface_create() funcion call.The size of the pdf file is specified in points, which is a standard in typesetting.

 cairo_show_page(cr);

The cairo_show_page() finishes rendering of the pdf file.


PDF file in Evince
PDF file in Evince

SVG file

The next example creates a simple SVG (Scalable Vector Graphics) file. The SVG is one of the hottest technologies these days.

#include <cairo.h>
#include <cairo-svg.h> 
 
int main() {

  cairo_surface_t *surface;
  cairo_t *cr;

  surface = cairo_svg_surface_create("svgfile.svg", 390, 60);
  cr = cairo_create(surface);

  cairo_set_source_rgb(cr, 0, 0, 0);
  cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
      CAIRO_FONT_WEIGHT_NORMAL);
  cairo_set_font_size (cr, 40.0);

  cairo_move_to(cr, 10.0, 50.0);
  cairo_show_text(cr, "Disziplin ist Macht.");

  cairo_surface_destroy(surface);
  cairo_destroy(cr);

  return 0;
}

We can use Firefox, Opera or Inkscape programs to open the svgfile.svg file.

 surface = cairo_svg_surface_create("svgfile.svg", 390, 60);

To create a SVG file in Cairo, we must create a svg surface using the cairo_svg_surface_create() function call.

The Rest of the code is identical to the previous examples.


SVG file in Opera
SVG file in Opera

GTK Window

In the last example, we will draw on the GTK window. This backend will be used throughout the rest of the tutorial

#include <cairo.h>
#include <gtk/gtk.h>

static gboolean
on_expose_event(GtkWidget      *widget,
                  GdkEventExpose *event,
                  gpointer        data)
{
  cairo_t *cr;

  cr = gdk_cairo_create(widget->window);

  cairo_set_source_rgb(cr, 0, 0, 0);
  cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
      CAIRO_FONT_WEIGHT_NORMAL);
  cairo_set_font_size(cr, 40.0);

  cairo_move_to(cr, 10.0, 50.0);
  cairo_show_text(cr, "Disziplin ist Macht.");

  cairo_destroy(cr);

  return FALSE;
}


int
main (int argc, char *argv[])
{

  GtkWidget *window;

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

  g_signal_connect(window, "expose-event",
                    G_CALLBACK (on_expose_event), NULL);
  g_signal_connect(window, "destroy",
                    G_CALLBACK (gtk_main_quit), NULL);

  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  gtk_window_set_default_size(GTK_WINDOW(window), 400, 90); 
  gtk_widget_set_app_paintable(window, TRUE);

  gtk_widget_show_all(window);

  gtk_main();

  return 0;
}

The example pops up a centered GTK+ window, on which we draw the "Disziplin ist Macht" text.

#include <cairo.h>
#include <gtk/gtk.h>

We include the necessary Cairo and GTK headers.

 g_signal_connect(window, "expose-event",
     G_CALLBACK(on_expose_event), NULL);

When the window is redrawn, an expose-event signal is emitted. We connect that signal to theon_expose_event() callback.

y gtk, part of a toolkits responsiveness is to redraw exposed regions whichfor normal windows will just 'clear' the background. if you want to drawyou own things in such a window, you need to inform gtk about that with thegtk_widget_set_app_paintable () function.
 gtk_widget_set_app_paintable(window, TRUE)

If we want to draw in GTK+, we can draw on a GtkDrawingArea widget or on a simple GtkWindow widget. I chose to draw on the latter. In order to draw on the GtkWindow widget, we must inform the GTK+ by calling the gtk_widget_set_app_paintable() call. The function call will suppress the default themed drawing of the widget's background. In case of the GtkDrawingArea, we do not need to call the function.

 cairo_t *cr;

 cr = gdk_cairo_create(widget->window);

The drawing is done inside the on_expose_event() callback function. We create a Cairo context for the GTK+ system and draw our text as usual on that context.


GTK window
GTK window

In this chapter we have covered supported Cairo backends.



内容概要:本文详细记录了对一个Android ARM64静态ELF文件中字符串加密机制的逆向分析过程。该ELF文件的所有字符串均被加密,无法通过常规strings命令或IDA直接识别。作者通过分析发现,加密字符串存储在.rodata段,其解密所需信息(包括密文地址、长度和16位密钥)保存在.data.rel.ro段的40字节描述符中。核心解密函数sub_10F408采用自反的双pass流密码算法,结合固定密钥KEY_TERM(由.data段24字节数据计算得出),实现字节级非线性、位置与长度相关的加密。文章还复现了完整的Python解密脚本,并揭示了该保护机制的本质为代码混淆而非强加密,最终成功批量解密全部956条字符串,暴露程序真实行为,如shell命令模板、设备标识篡改、网络重置等操作。此外,文中还提及未启用的自定义壳框架及其反dump设计。; 适合人群:具备逆向工程基础的安全研究人员、二进制分析人员及对ELF保护技术感兴趣的开发者。; 使用场景及目标:①学习ELF二进制中字符串加密的典型实现方式与逆向突破口;②掌握从结构识别、函数追踪到算法还原的完整逆向流程;③理解“绑定二进制”的完整性校验设计及其局限性;④实践编写IDAPython脚本自动化提取与解密敏感数据。; 阅读建议:此资源以实战案例驱动,不仅展示技术细节,更强调逆向思维与验证方法,建议读者结合IDA调试环境,逐步跟随文中步骤进行动态分析与算法验证,深入理解每一步的推理依据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值