@@ -33,6 +33,10 @@ public:
3333 std::function<void (hook::pattern_match)> CB,
3434 bool translate = true);
3535
36+ void FindCodePattern (std::string_view pattern,
37+ std::function<void (uint32_t )> CB,
38+ bool translate = true);
39+
3640 void FindString (const char *str, void (*CB) (char *));
3741
3842 template <typename ... Args>
@@ -371,7 +375,7 @@ public:
371375class YscUtilsOps : public YscUtils
372376{
373377 bool bOperationFailed = false ;
374- uint8_t *pPatternResult = nullptr ;
378+ uint32_t nPatternResultIp = - 1u ;
375379
376380public:
377381 using YscUtils::YscUtils;
@@ -380,29 +384,24 @@ public:
380384 void
381385 Init (std::string_view pattern, bool translate = true )
382386 {
383- uint8_t *ptr = nullptr ;
384- FindCodePattern (pattern, [&ptr] (hook::pattern_match m) {
385- if (!ptr)
386- ptr = m.get <uint8_t > (0 );
387- });
388-
389- pPatternResult = ptr;
387+ nPatternResultIp = -1u ;
388+ FindCodePattern (pattern, [this ] (uint32_t match) {
389+ if (nPatternResultIp == -1u )
390+ nPatternResultIp = match;
391+ }, translate);
390392 }
391393
392394 /* Initialise the UtilsOps to a certain pattern for further operations */
393395 void
394396 Init (uint32_t ip)
395397 {
396- uint8_t *ptr = &GetProgram ()->GetCodeByte <uint8_t > (ip);
397- pPatternResult = ptr;
398+ nPatternResultIp = ip;
398399 }
399400
400401 uint32_t
401402 GetWorkingIp ()
402403 {
403- if (pPatternResult)
404- return GetCodeOffset (pPatternResult);
405- return -1u ;
404+ return nPatternResultIp;
406405 }
407406
408407 /* Reinitialises the UtilsOps to the branch destination at offset of stored
@@ -414,8 +413,7 @@ public:
414413 {
415414 // Absolute offset
416415 case YscOpCode::CALL:
417- pPatternResult = &GetProgram ()->GetCodeByte <uint8_t > (
418- (*Get<uint32_t > (offset) >> 8 ));
416+ nPatternResultIp = (*Get<uint32_t > (offset) >> 8 );
419417 break ;
420418
421419 // Relative offset
@@ -427,7 +425,7 @@ public:
427425 case YscOpCode::IGE_JZ:
428426 case YscOpCode::ILT_JZ:
429427 case YscOpCode::ILE_JZ:
430- pPatternResult += *Get<uint16_t > (offset + 1 ) + (offset + 3 );
428+ nPatternResultIp += *Get<uint16_t > (offset + 1 ) + (offset + 3 );
431429 break ;
432430
433431 default : bOperationFailed = true ; break ;
@@ -439,24 +437,37 @@ public:
439437 T *
440438 Get (int64_t offset)
441439 {
442- return reinterpret_cast <T * > (pPatternResult + offset);
440+ return & GetProgram ()-> GetCodeByte <T > (nPatternResultIp + offset);
443441 }
444442
445443 /* Makes a NOP at offset of size */
446444 void
447445 NOP (int64_t offset, size_t size)
448446 {
449- if (!pPatternResult )
447+ if (nPatternResultIp == - 1u )
450448 return void (bOperationFailed = true );
451- memset (pPatternResult + offset, uint8_t (YscOpCode::NOP), size);
449+
450+ while (size != 0 )
451+ {
452+ size_t nopSize
453+ = std::min (size_t (GetProgram ()->GetPageSizeLeft (
454+ nPatternResultIp + offset)),
455+ size);
456+
457+ memset (Get<uint8_t > (offset), uint8_t (YscOpCode::NOP),
458+ nopSize);
459+
460+ size -= nopSize;
461+ offset += nopSize;
462+ }
452463 }
453464
454465 /* Writes a value of type T at offset */
455466 template <typename T>
456467 void
457468 Write (int64_t offset, T value)
458469 {
459- if (!pPatternResult )
470+ if (nPatternResultIp == - 1u )
460471 return void (bOperationFailed = true );
461472 *Get<T> (offset) = value;
462473 }
@@ -465,13 +476,13 @@ public:
465476 void
466477 WriteBytes (int64_t offset, const T &bytes)
467478 {
468- if (!pPatternResult )
479+ if (nPatternResultIp == - 1u )
469480 return void (bOperationFailed = true );
470- memcpy (pPatternResult + offset, &bytes[0 ], std::size (bytes));
481+ memcpy (Get< uint8_t > ( offset) , &bytes[0 ], std::size (bytes));
471482 }
472483
473484 explicit operator bool () const
474485 {
475- return bOperationFailed || !pPatternResult ;
486+ return bOperationFailed || nPatternResultIp == - 1u ;
476487 }
477488};
0 commit comments