// because strdup is apparently not in <string.h> char* my_strdup(const char* str) { size_t len = strlen(str) + 1; char* ret = malloc_s(len * sizeof(char)); for (size_t i = 0; i < len; i++) *(ret + i) = *(str + i); return ret; }
static NODE_PERES * createNode(NODE_PERES *currentNode, NODE_TYPE_PERES typeOfNextNode) { assert(currentNode != NULL); NODE_PERES *newNode = malloc_s(sizeof(NODE_PERES)); newNode->lastNode = currentNode; newNode->nextNode = NULL; newNode->nodeType = typeOfNextNode; currentNode->nextNode = newNode; return newNode; }
static options_t *parse_options(int argc, char *argv[]) { options_t *options = malloc_s(sizeof(options_t)); memset(options, 0, sizeof(options_t)); /* Parameters for getopt_long() function */ static const char short_options[] = "a:x:i:s:v"; static const struct option long_options[] = { { "all", required_argument, NULL, 'a' }, { "extract", no_argument, NULL, 'x' }, { "info", no_argument, NULL, 'i' }, { "statistics", no_argument, NULL, 's' }, { "version", no_argument, NULL, 'v' }, { "help", no_argument, NULL, 1 }, { NULL, 0, NULL, 0 } }; //memset(&config, false, sizeof(config)); int c, ind; while ((c = getopt_long(argc, argv, short_options, long_options, &ind))) { if (c < 0) break; switch (c) { case 'a': options->all = true; break; case 'x': options->extract = true; break; case 'i': options->info = true; break; case 's': options->statistics = true; break; case 'v': printf("%s %s\n%s\n", PROGRAM, TOOLKIT, COPY); exit(EXIT_SUCCESS); case 1: // --help option usage(); exit(EXIT_SUCCESS); default: fprintf(stderr, "%s: try '--help' for more information\n", PROGRAM); exit(EXIT_FAILURE); } } return options; }
static options_t *parse_options(int argc, char *argv[]) { options_t *options = malloc_s(sizeof(options_t)); memset(options, 0, sizeof(options_t)); /* Parameters for getopt_long() function */ static const char short_options[] = "osn:v"; static const struct option long_options[] = { { "offset", no_argument, NULL, 'o' }, { "section", no_argument, NULL, 's' }, { "min-length", required_argument, NULL, 'n' }, { "help", no_argument, NULL, 1 }, { "version", no_argument, NULL, 3 }, { NULL, 0, NULL, 0 } }; int c, ind; while ((c = getopt_long(argc, argv, short_options, long_options, &ind))) { if (c < 0) break; switch (c) { case 1: // --help option usage(); exit(EXIT_SUCCESS); case 'o': options->offset = true; break; case 's': options->section = true; break; case 'n': { unsigned long value = strtoul(optarg, NULL, 0); if (value == ULONG_MAX && errno == ERANGE) { fprintf(stderr, "The original (nonnegated) value would overflow"); exit(EXIT_FAILURE); } options->strsize = (unsigned char)value; break; } case 'v': printf("%s %s\n%s\n", PROGRAM, TOOLKIT, COPY); exit(EXIT_SUCCESS); default: fprintf(stderr, "%s: try '--help' for more information\n", PROGRAM); exit(EXIT_FAILURE); } } return options; }
static options_t *parse_options(int argc, char *argv[]) { options_t *options = malloc_s(sizeof(options_t)); memset(options, 0, sizeof(options_t)); /* Parameters for getopt_long() function */ static const char short_options[] = "f:c:o:v"; static const struct option long_options[] = { { "format", required_argument, NULL, 'f' }, { "certoutform", required_argument, NULL, 'c' }, { "certout", required_argument, NULL, 'o' }, { "help", no_argument, NULL, 1 }, { "version", no_argument, NULL, 'v' }, { NULL, 0, NULL, 0 } }; int c, ind; while ((c = getopt_long(argc, argv, short_options, long_options, &ind))) { if (c < 0) break; switch (c) { case 1: // --help option usage(); exit(EXIT_SUCCESS); case 'f': if (output_set_format_by_name(optarg) < 0) EXIT_ERROR("invalid format option"); break; case 'v': printf("%s %s\n%s\n", PROGRAM, TOOLKIT, COPY); exit(EXIT_SUCCESS); case 'c': options->certoutform = parse_certoutform(optarg); break; case 'o': options->certout = parse_certout(optarg); break; default: fprintf(stderr, "%s: try '--help' for more information\n", PROGRAM); exit(EXIT_FAILURE); } } return options; }
static bool compare_signature(const unsigned char *data, uint64_t ep_offset, FILE *dbfile, char *packer_name, size_t packer_name_len) { if (!dbfile || !data) return false; char *buff = malloc_s(MAX_SIG_SIZE); //memset(buff, 0, MAX_SIG_SIZE); while (fgets(buff, MAX_SIG_SIZE, dbfile)) { // line length size_t len = strlen(buff); // ifgore comments and blank lines if (*buff == ';' || *buff == '\n' || *buff == '\r') continue; // remove newline from buffer if (*(buff+len-1) == '\n') *(buff+len-1) = '\0'; // removing carriage return, if present if (*(buff+len-2) == '\r') { *(buff+len-2) = '\0'; //*(buff+len-1) = '\0'; len--; // update line length } // line have [packer name]? Fill packer_name pointer if (*buff == '[' && *(buff+len-2) == ']') { *(buff+len-2) = '\0'; // remove square brackets strncpy(packer_name, buff+1, packer_name_len); packer_name[packer_name_len-1] = '\0'; // Guarantee it's Null-terminated. } // check if signature match if (!strncasecmp(buff, "signature", 9)) { if (match_peid_signature(data + ep_offset, buff+9)) { free(buff); return true; } } } free(buff); return false; }
// Download memory from the GPU float* dlMem(struct Interop interop, int key, size_t* memSize, size_t screenSizeBytes) { cl_mem clmem = getMem(interop, key, memSize); if (!clmem) return NULL; if (*memSize == 0) *memSize = screenSizeBytes; float* data = malloc_s(*memSize); if (PrintErr(clEnqueueReadBuffer(interop.command_queue, clmem, 1, 0, *memSize, data, 0, NULL, NULL))) { free(data); return NULL; } return data; }
static void print_basic_hash(const unsigned char *data, size_t data_size) { if (!data || !data_size) return; const char *basic_hashes[] = { "md5", "sha1", "sha256", "ssdeep" }; const size_t hash_value_size = pe_hash_recommended_size(); char *hash_value = malloc_s(hash_value_size); for (size_t i=0; i < sizeof(basic_hashes) / sizeof(char *); i++) { pe_hash_raw_data(hash_value, hash_value_size, basic_hashes[i], data, data_size); output(basic_hashes[i], hash_value); } free(hash_value); }
/* シート作成関数 create_sheet関数とsheet_init関数の共通部を関数化したもの */ struct SHEET *SHTCTL::g_sheet(short vx, short vy, short xsize, short ysize){ SHEET *sheet=(SHEET *)malloc_s(xsize*ysize*4+sizeof(SHEET)) ; //引数代入 sheet->vx=vx ; sheet->vy=vy ; sheet->xsize=xsize ; sheet->ysize=ysize ; //フラグセット、透過情報なし、表示 sheet->flag=1 ; sheet->buffer=(int *)sheet+sizeof(SHEET) ; return sheet ; }
/* ウィンドウシート作成関数 */ struct WINDOW *SHTCTL::g_winsheet(short vx, short vy, short xsize, short ysize){ WINDOW *window=(WINDOW *)malloc_s(xsize*ysize*4+sizeof(WINDOW)) ; window->this_s_p=&(window->this_s) ; //引数代入 window->this_s.vx=vx ; window->this_s.vy=vy ; window->this_s.xsize=xsize ; window->this_s.ysize=ysize ; //フラグセット、透過情報なし、表示 window->this_s.flag=1 ; window->this_s.buffer=(int *)window->this_s_p+sizeof(SHEET) ; return window ; }
// Reads an entire binary file void* readWholeBinFile(const char* filename, size_t* size) { FILE* f = fopen(filename, "rb"); if (!f) { perror("readWholeBinFile()"); return NULL; } fseek(f, 0, SEEK_END); *size = (size_t)ftell(f); fseek(f, 0, SEEK_SET); char* string = malloc_s(*size); fread(string, *size, 1, f); fclose(f); return string; }
// Allocates and appends the pre-allocated cl_mem key/value pair to the list int addMem(struct Interop* interop, int key, cl_mem mem, size_t memSize) { struct cl_mem_list** toAssign = &interop->clMems; while (*toAssign) { if ((*toAssign)->key == key) { printf("Buffer ID %d already exists, cannot create it\n", key); return -1; } toAssign = &(*toAssign)->next; } *toAssign = malloc_s(sizeof(struct cl_mem_list)); (*toAssign)->key = key; (*toAssign)->memory = mem; (*toAssign)->memorySize = memSize; (*toAssign)->next = NULL; return 0; }
// Reads an entire binary file char* readWholeFile(const char* filename) { FILE* f = fopen(filename, "rb"); if (!f) { perror("readWholeFile()"); return NULL; } fseek(f, 0, SEEK_END); size_t fsize = (size_t)ftell(f); fseek(f, 0, SEEK_SET); char* string = malloc_s(fsize + 1); fread(string, fsize, 1, f); fclose(f); string[fsize] = 0; return string; }
/** * @brief Gauss elimination with partial pivoting proportionally * @param N The numbers of the variables * @param a The coefficient matrix in a 1-dimension array * @param b The constant vector * @return An array of numbers, NULL if the equation has no solution */ double *GaussEliPPP(int N, double *a, double *b) { double **A = (double**)malloc_s(N * sizeof(double*)); for (int i = 0; i < N; i++) { A[i] = (double*)malloc_s((N + 1) * sizeof(double)); for (int j = 0; j < N; j++) { A[i][j] = a[i * N + j]; } A[i][N] = b[i]; } double *max = (double*)malloc_s(N * sizeof(double)); double *x = (double*)malloc_s(N * sizeof(double)); /* get the largest number of each line */ for (int i = 0; i < N; i++) { max[i] = 0; for (int j = 0; j < N; j++) { max[i] = (fabs(max[i]) < fabs(A[i][j])) ? fabs(A[i][j]) : max[i]; } if (fabs(max[i]) < FLOAT_ZERO_LIM) { fprintf(stderr, "GaussEliPPP: A is singular\n"); return NULL; } } // do the gauss elimination with partial pivoting proportionally for (int k = 0; k < N - 1; k++) { int r = k; // choose the pivot element for (int i = k; i < N; i++) { r = (fabs(A[r][k] / max[r]) < fabs(A[i][k] / max[i])) ? i : r; } if (fabs(A[r][k]) < FLOAT_ZERO_LIM) { printf("A is singular\n"); return NULL; } if (r != k) { double q = max[k]; max[k] = max[r]; max[r] = q; double *t = A[k]; A[k] = A[r]; A[r] = t; } for (int i = k + 1; i < N; i++) { A[i][k] = A[i][k] / A[k][k]; for (int j = k + 1; j < N + 1; j++) { A[i][j] -= A[i][k] * A[k][j]; } } } if (fabs(A[N - 1][N - 1]) < FLOAT_ZERO_LIM) { printf("A is singular\n"); return NULL; } for (int k = N - 1; k >= 0; k--) { double t = 0; for (int j = k + 1; j < N; j++) { t += A[k][j] * x[j]; } x[k] = (A[k][N] - t) / A[k][k]; } free(max); return x; }
static options_t *parse_options(int argc, char *argv[]) { options_t *options = malloc_s(sizeof(options_t)); memset(options, 0, sizeof(options_t)); // parameters for getopt_long() function static const char short_options[] = "f:a:c:h:s:V"; static const struct option long_options[] = { { "help", no_argument, NULL, 1 }, { "format", required_argument, NULL, 'f' }, { "all", no_argument, NULL, 'a' }, { "content", no_argument, NULL, 'c' }, { "header", required_argument, NULL, 'h' }, { "section-name", required_argument, NULL, 's' }, { "section-index", required_argument, NULL, 2 }, { "version", no_argument, NULL, 'V' }, { NULL, 0, NULL, 0 } }; // Setting the default option options->content = true; int c, ind; while ((c = getopt_long(argc, argv, short_options, long_options, &ind))) { if (c < 0) break; switch (c) { case 1: // --help option usage(); exit(EXIT_SUCCESS); case 'f': if (output_set_format_by_name(optarg) < 0) EXIT_ERROR("invalid format option"); break; case 'a': options->all = true; break; case 'c': // default options->all = false; //TODO remover? options->content = true; break; case 's': options->all = false; options->headers.all = false; // TODO: How do we need to handle non-ascii names? options->sections.name = strdup(optarg); break; case 2: options->all = false; options->headers.all = false; options->sections.index = strtol(optarg, NULL, 10); if (options->sections.index < 1 || options->sections.index > MAX_SECTIONS) { EXIT_ERROR("Bad argument for section-index,"); } break; case 'V': printf("%s %s\n%s\n", PROGRAM, TOOLKIT, COPY); exit(EXIT_SUCCESS); case 'h': options->all = false; options->headers.all = false; parse_header_name(options, optarg); break; default: fprintf(stderr, "%s: try '--help' for more information\n", PROGRAM); exit(EXIT_FAILURE); } } // TODO: Warn about simultaneous usage of -h, -s, and --section-index. return options; }
static NODE_PERES * discoveryNodesPeres(pe_ctx_t *ctx) { #ifdef LIBPE_ENABLE_OUTPUT_COMPAT_WITH_V06 typedef struct { ImageDirectoryEntry entry; const char * const name; } ImageDirectoryEntryName; static const ImageDirectoryEntryName directoryEntryNames[] = { { IMAGE_DIRECTORY_ENTRY_EXPORT, "Export Table" }, // "Export directory", { IMAGE_DIRECTORY_ENTRY_IMPORT, "Import Table" }, // "Import directory", { IMAGE_DIRECTORY_ENTRY_RESOURCE, "Resource Table" }, // "Resource directory", { IMAGE_DIRECTORY_ENTRY_EXCEPTION, "Exception Table" }, // "Exception directory", { IMAGE_DIRECTORY_ENTRY_SECURITY, "Certificate Table" }, // "Security directory", { IMAGE_DIRECTORY_ENTRY_BASERELOC, "Base Relocation Table" }, // "Base relocation table", { IMAGE_DIRECTORY_ENTRY_DEBUG, "Debug" }, // "Debug directory", { IMAGE_DIRECTORY_ENTRY_ARCHITECTURE, "Architecture" }, // "Architecture-specific data", { IMAGE_DIRECTORY_ENTRY_GLOBALPTR, "Global Ptr" }, // "Global pointer", { IMAGE_DIRECTORY_ENTRY_TLS, "Thread Local Storage (TLS)"}, // "Thread local storage (TLS) directory", { IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG, "Load Config Table" }, // "Load configuration directory", { IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT, "Bound Import" }, // "Bound import directory", { IMAGE_DIRECTORY_ENTRY_IAT, "Import Address Table (IAT)"}, // "Import address table (IAT)", { IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT, "Delay Import Descriptor" }, // "Delay import table", { IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR, "CLR Runtime Header" }, // "COM descriptor table" { IMAGE_DIRECTORY_RESERVED, "" } // "Reserved" }; //static const size_t max_directory_entry = LIBPE_SIZEOF_ARRAY(names); #endif const IMAGE_DATA_DIRECTORY * const resourceDirectory = pe_directory_by_entry(ctx, IMAGE_DIRECTORY_ENTRY_RESOURCE); if (resourceDirectory == NULL || resourceDirectory->Size == 0) return NULL; uint64_t resourceDirOffset = pe_rva2ofs(ctx, resourceDirectory->VirtualAddress); char s[MAX_MSG]; if (resourceDirectory->Size != 0) { snprintf(s, MAX_MSG, "%#x (%d bytes)", resourceDirectory->VirtualAddress, resourceDirectory->Size); #ifdef LIBPE_ENABLE_OUTPUT_COMPAT_WITH_V06 output(directory_names[IMAGE_DIRECTORY_ENTRY_RESOURCE], s); // Resource table #else output(pe_directory_name(IMAGE_DIRECTORY_ENTRY_RESOURCE), s); // Resource table #endif //printf("Offset by RVA: 0x%x\n\n", resourceDirOffset); } uintptr_t offset = resourceDirOffset; void *ptr = LIBPE_PTR_ADD(ctx->map_addr, offset); if (LIBPE_IS_PAST_THE_END(ctx, ptr, sizeof(IMAGE_RESOURCE_DIRECTORY))) { // TODO: Should we report something? return NULL; } NODE_PERES *node = malloc_s(sizeof(NODE_PERES)); node->lastNode = NULL; // root node->nodeType = RDT_RESOURCE_DIRECTORY; node->nodeLevel = RDT_LEVEL1; node->resource.resourceDirectory = ptr; //showNode(node); for (int i = 1, offsetDirectory1 = 0; i <= (lastNodeByTypeAndLevel(node, RDT_RESOURCE_DIRECTORY, RDT_LEVEL1)->resource.resourceDirectory->NumberOfNamedEntries + lastNodeByTypeAndLevel(node, RDT_RESOURCE_DIRECTORY, RDT_LEVEL1)->resource.resourceDirectory->NumberOfIdEntries); i++) { offsetDirectory1 += (i == 1) ? 16 : 8; offset = resourceDirOffset + offsetDirectory1; ptr = LIBPE_PTR_ADD(ctx->map_addr, offset); if (LIBPE_IS_PAST_THE_END(ctx, ptr, sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY))) { // TODO: Should we report something? goto _error; } node = createNode(node, RDT_DIRECTORY_ENTRY); NODE_PERES *rootNode = node; node->rootNode = rootNode; node->nodeLevel = RDT_LEVEL1; node->resource.directoryEntry = ptr; //showNode(node); const NODE_PERES * lastDirectoryEntryNodeAtLevel1 = lastNodeByTypeAndLevel(node, RDT_DIRECTORY_ENTRY, RDT_LEVEL1); if (lastDirectoryEntryNodeAtLevel1->resource.directoryEntry->DirectoryData.data.DataIsDirectory) { offset = resourceDirOffset + lastDirectoryEntryNodeAtLevel1->resource.directoryEntry->DirectoryData.data.OffsetToDirectory; ptr = LIBPE_PTR_ADD(ctx->map_addr, offset); if (LIBPE_IS_PAST_THE_END(ctx, ptr, sizeof(IMAGE_RESOURCE_DIRECTORY))) { // TODO: Should we report something? goto _error; } node = createNode(node, RDT_RESOURCE_DIRECTORY); node->rootNode = (NODE_PERES *)lastDirectoryEntryNodeAtLevel1; node->nodeLevel = RDT_LEVEL2; node->resource.resourceDirectory = ptr; //showNode(node); for (int j = 1, offsetDirectory2 = 0; j <= (lastNodeByTypeAndLevel(node, RDT_RESOURCE_DIRECTORY, RDT_LEVEL2)->resource.resourceDirectory->NumberOfNamedEntries + lastNodeByTypeAndLevel(node, RDT_RESOURCE_DIRECTORY, RDT_LEVEL2)->resource.resourceDirectory->NumberOfIdEntries); j++) { offsetDirectory2 += (j == 1) ? 16 : 8; offset = resourceDirOffset + lastNodeByTypeAndLevel(node, RDT_DIRECTORY_ENTRY, RDT_LEVEL1)->resource.directoryEntry->DirectoryData.data.OffsetToDirectory + offsetDirectory2; ptr = LIBPE_PTR_ADD(ctx->map_addr, offset); if (LIBPE_IS_PAST_THE_END(ctx, ptr, sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY))) { // TODO: Should we report something? goto _error; } node = createNode(node, RDT_DIRECTORY_ENTRY); node->rootNode = rootNode; node->nodeLevel = RDT_LEVEL2; node->resource.directoryEntry = ptr; //showNode(node); offset = resourceDirOffset + node->resource.directoryEntry->DirectoryData.data.OffsetToDirectory; // posiciona em 0x72 ptr = LIBPE_PTR_ADD(ctx->map_addr, offset); if (LIBPE_IS_PAST_THE_END(ctx, ptr, sizeof(IMAGE_RESOURCE_DIRECTORY))) { // TODO: Should we report something? goto _error; } node = createNode(node, RDT_RESOURCE_DIRECTORY); node->rootNode = rootNode; node->nodeLevel = RDT_LEVEL3; node->resource.resourceDirectory = ptr; //showNode(node); offset += sizeof(IMAGE_RESOURCE_DIRECTORY); for (int y = 1; y <= (lastNodeByTypeAndLevel(node, RDT_RESOURCE_DIRECTORY, RDT_LEVEL3)->resource.resourceDirectory->NumberOfNamedEntries + lastNodeByTypeAndLevel(node, RDT_RESOURCE_DIRECTORY, RDT_LEVEL3)->resource.resourceDirectory->NumberOfIdEntries); y++) { ptr = LIBPE_PTR_ADD(ctx->map_addr, offset); if (LIBPE_IS_PAST_THE_END(ctx, ptr, sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY))) { // TODO: Should we report something? goto _error; } node = createNode(node, RDT_DIRECTORY_ENTRY); node->rootNode = rootNode; node->nodeLevel = RDT_LEVEL3; node->resource.directoryEntry = ptr; //showNode(node); offset = resourceDirOffset + node->resource.directoryEntry->DirectoryName.name.NameOffset; ptr = LIBPE_PTR_ADD(ctx->map_addr, offset); if (LIBPE_IS_PAST_THE_END(ctx, ptr, sizeof(IMAGE_RESOURCE_DATA_STRING))) { // TODO: Should we report something? goto _error; } node = createNode(node, RDT_DATA_STRING); node->rootNode = rootNode; node->nodeLevel = RDT_LEVEL3; node->resource.dataString = ptr; //showNode(node); offset = resourceDirOffset + node->lastNode->resource.directoryEntry->DirectoryData.data.OffsetToDirectory; ptr = LIBPE_PTR_ADD(ctx->map_addr, offset); if (LIBPE_IS_PAST_THE_END(ctx, ptr, sizeof(IMAGE_RESOURCE_DATA_ENTRY))) { // TODO: Should we report something? goto _error; } node = createNode(node, RDT_DATA_ENTRY); node->rootNode = rootNode; node->nodeLevel = RDT_LEVEL3; node->resource.dataEntry = ptr; //showNode(node); offset += sizeof(IMAGE_RESOURCE_DATA_ENTRY); } } } } return node; _error: if (node != NULL) freeNodes(node); return NULL; }
bool SvgInit(unsigned int w, unsigned int h, const char *file, struct ADrawTag *outContext) { SvgContext *context; /* Create context */ context = outContext->internal = malloc_s(sizeof(SvgContext)); if(context == NULL) { return false; } /* Open the output file */ if(strcmp(file, "-") == 0) { context->of = stdout; } else { context->of = fopen(file, "wb"); if(!context->of) { fprintf(stderr, "SvgInit: Failed to open output file '%s': %s\n", file, strerror(errno)); return false; } } /* Set the initial pen state */ SvgSetPen(outContext, ADRAW_COL_BLACK); SvgSetBgPen(outContext, ADRAW_COL_WHITE); /* Default to small font */ SvgSetFontSize(outContext, ADRAW_FONT_SMALL); fprintf(context->of, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n" " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"); fprintf(context->of, "<svg version=\"1.1\"\n" " width=\"%upx\" height=\"%upx\"\n" " viewBox=\"0 0 %u %u\"\n" " xmlns=\"http://www.w3.org/2000/svg\" shape-rendering=\"crispEdges\"\n" " stroke-width=\"1\" text-rendering=\"geometricPrecision\"\n" " xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n", w, h, w, h); /* Now fill in the function pointers */ outContext->line = SvgLine; outContext->dottedLine = SvgDottedLine; outContext->textL = SvgTextL; outContext->textC = SvgTextC; outContext->textR = SvgTextR; outContext->textWidth = SvgTextWidth; outContext->textHeight = SvgTextHeight; outContext->filledRectangle = SvgFilledRectangle; outContext->filledTriangle = SvgFilledTriangle; outContext->filledCircle = SvgFilledCircle; outContext->arc = SvgArc; outContext->dottedArc = SvgDottedArc; outContext->setPen = SvgSetPen; outContext->setBgPen = SvgSetBgPen; outContext->setFontSize = SvgSetFontSize; outContext->close = SvgClose; return true; }